MongoDB 'count()' очень медленный. Как мы усовершенствуем/работаем с ним? - программирование
Подтвердить что ты не робот

MongoDB 'count()' очень медленный. Как мы усовершенствуем/работаем с ним?

В настоящее время я использую MongoDB с миллионами записей данных. Я обнаружил одну вещь, которая очень раздражает.

Когда я использую функцию count() с небольшим количеством запрошенных данных, это очень быстро. Однако, когда запрашиваемый сбор данных содержит тысячи или даже миллионы записей данных, вся система становится очень медленной.

Я убедился, что проиндексировал необходимые поля.

Кто-нибудь сталкивался с тем же? Как вы это сделаете, чтобы улучшить это?

4b9b3361

Ответ 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 с - с нерезким индексом