MongoDB - слишком много данных для sort () без ошибки индекса - PullRequest
21 голосов
/ 09 декабря 2010

Я использую 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 ]

14 голосов
/ 09 декабря 2010

Попробуйте добавить {community_id: 1, 'updated_at.t': -1} индекс.Сначала нужно выполнить поиск по community_id, а затем отсортировать.

4 голосов
/ 09 декабря 2010

То есть, вы чувствуете, что используете индекс, но на самом деле индекс является составным.Я не уверен, что сортировка "достаточно умна", чтобы использовать только частичный индекс.

Итак, две проблемы:

  1. Исходя из вашего запроса, я бы поставил community_id в качествеПервая часть индекса, а не вторая.updated_at.t звучит как поле, к которому вы будете выполнять запросы диапазона.Индексы работают лучше, если запрос диапазона является вторым битом.
  2. Сколько записей вернется из community_id => 1?Если число не велико, вам, возможно, удастся обойтись без простой сортировки без индекса.

Так что вам, возможно, придется переключить индекс, и вам, возможно, придется изменить сортировку, чтобы использовать обаcommunity_id и updated_at.t.Я знаю, что это кажется излишним, но начните с него и проверьте группы Google, если он все еще не работает.

2 голосов
/ 16 июня 2011

Даже с индексом, я думаю, что вы все равно можете получить эту ошибку, если ваш набор результатов превышает 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
}
0 голосов
/ 07 ноября 2013

Слишком большой размер пакета курсора вызовет эту ошибку. Установка размера пакета не ограничивает объем данных, которые вы можете обрабатывать, а ограничивает объем данных, возвращаемых из базы данных. Когда вы выполните итерацию и достигнете предела партии, процесс совершит еще одну поездку в базу данных.

...