MongoDB - слишком много данных для sort() без ошибки индекса
Я использую MongoDB 1.6.3, для хранения большой коллекции (более 300 тыс. Записей). Я добавил составной индекс.
db['collection_name'].getIndexes()
[
{
"name" : "_id_",
"ns" : "db_name.event_logs",
"key" : {
"_id" : 1
}
},
{
"key" : {
"updated_at.t" : -1,
"community_id" : 1
},
"ns" : "db_name.event_logs",
"background" : true,
"name" : "updated_at.t_-1_community_id_1"
}
]
Тем не менее, когда я пытаюсь запустить этот код:
db['collection_name']
.find({:community_id => 1})
.sort(['updated_at.t', -1])
.skip(@skip)
.limit(@limit)
Я получаю:
Mongo:: OperationFailure (слишком много данных для sort() без индекса. Добавить индекс или указать меньший предел)
Что я делаю неправильно?
4 ответа
Попробуйте добавить {community_id: 1, 'updated_at.t': -1}
индекс. Нужно искать по community_id
сначала и потом сортируй.
Таким образом, вы чувствуете, что используете индекс, но на самом деле индекс является составным. Я не уверен, что сортировка "достаточно умна", чтобы использовать только частичный индекс.
Итак, две проблемы:
- Исходя из вашего запроса, я бы назвал community_id первой частью индекса, а не второй.
updated_at.t
звучит как поле, по которому вы будете выполнять запросы диапазона. Индексы работают лучше, если запрос диапазона является вторым битом. - Сколько записей вернется из
community_id => 1
? Если число не велико, вам, возможно, удастся просто отсортировать без индекса.
Таким образом, вам, возможно, придется изменить индекс, и вам, возможно, придется изменить сортировку, чтобы использовать оба community_id
а также updated_at.t
, Я знаю, что это кажется излишним, но начните там и проверьте Группы Google, если это все еще не работает.
Даже с индексом, я думаю, вы все равно можете получить эту ошибку, если ваш набор результатов превышает 4 МБ.
Вы можете увидеть размер, зайдя в консоль mongodb и выполнив это:
show dbs
# pick yours (e.g., production)
use db-production
db.articles.stats()
Я закончил с результатами, как это:
{
"ns" : "mdalert-production.encounters",
"count" : 89077,
"size" : 62974416,
"avgObjSize" : 706.9660630690302,
"storageSize" : 85170176,
"numExtents" : 8,
"nindexes" : 6,
"lastExtentSize" : 25819648,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 18808832,
"indexSizes" : {
"_id_" : 3719168,
"patient_num_1" : 3440640,
"msg_timestamp_1" : 2981888,
"practice_id_1" : 2342912,
"patient_id_1" : 3342336,
"msg_timestamp_-1" : 2981888
},
"ok" : 1
}
Слишком большой размер пакета курсора вызовет эту ошибку. Установка размера пакета не ограничивает объем данных, которые вы можете обрабатывать, а ограничивает объем данных, возвращаемых из базы данных. Когда вы выполните итерацию и достигнете предела партии, процесс совершит еще одну поездку в базу данных.