MongoDB 'count()' очень медленный. Как мы усовершенствуем/работаем с ним?
В настоящее время я использую MongoDB с миллионами записей данных. Я обнаружил одну вещь, которая очень раздражает.
Когда я использую функцию count() с небольшим количеством запрошенных данных, это очень быстро. Однако, когда запрашиваемый сбор данных содержит тысячи или даже миллионы записей данных, вся система становится очень медленной.
Я убедился, что проиндексировал необходимые поля.
Кто-нибудь сталкивался с тем же? Как вы это сделаете, чтобы улучшить это?
Ответы
Ответ 1
Теперь существует еще одна оптимизация, чем создание правильного индекса.
db.users.ensureIndex({name:1});
db.users.find({name:"Andrei"}).count();
Если вам нужны какие-то счетчики, я предлагаю их предварительно рассчитать, когда это возможно. Используя атомную $inc, и не используйте count({})
вообще.
Но MongoDB ребята работают тяжело MongoDB, поэтому, count({})
улучшения они планируют в MongoDB 2.1 в соответствии с JIRA ошибка.Р >
Ответ 2
Вы можете убедиться, что индекс действительно используется без доступа к диску.
Скажем, вы хотите подсчитать записи с именем: "Андрей"
Вы гарантируете индекс по имени (как вы это сделали)
и
db.users.find({name:"andrei"}, {_id:0, name:1}).count()
вы можете проверить, что это самый быстрый способ подсчета (за исключением предварительного вычисления), проверяя, что
db.users.find({name:"andrei"}, {_id:0, name:1}).explain()
отображает поле index_only, заданное как true.
Этот трюк гарантирует, что ваш запрос будет извлекать записи только из ram (index), а не из диска.
Ответ 3
На данный момент вам очень не повезло, считать в mongodb ужасно и не будет улучшаться в ближайшем будущем. См.: https://jira.mongodb.org/browse/SERVER-1752
Из опыта вы почти никогда не будете использовать его, если это одноразовая вещь, что происходит очень редко, или ваша база данных довольно маленькая.
Как сказал @Andrew Orsich, используйте счетчики, когда это возможно (падение на счетчики является глобальной блокировкой записи, но лучше, чем count() независимо).
Ответ 4
Для меня решение было индексом изменения разреженным.
Это зависит от конкретной ситуации, просто попробуйте, если сможете.
db.Account.createIndex( { "date_checked_1": 1 }, { sparse: true } )
db.Account.find({
"dateChecked" : { $exists : true }
}).count()
318 тысяч записей в коллекции
- 0,31 с - с разреженным индексом
- 0,79 с - с нерезким индексом