2014-02-26 1 views
3

Я сохраняю документы для игр в MongoDB. Среди прочего, документы содержат имя игрока (имя), время окончания игры (endMS) и тип игры (тип). Тип может иметь одно из пяти разных значений.Почему MongoDB использует scanAndOrder здесь?

Мне нужно найти все готовые игры игрока, отсортированного по времени окончания игры и для всех законченных игр игрока с определенным типом игры, также отсортированным по времени окончания игры.

Примеры для обоих запросов являются

db.games.find ({имя: "Стефан", endMS: {$ Gt: 0}}). Сортировки ({endMS: -1})

и

db.games.find ({имя: "Стефан", тип: "л", endMS: {$ Gt: 0}}). сортировки ({endMS: -1})

Вы можете использовать индексы

db.games.ensureIndex ({имя: 1, endMS: -1})

и

db.games.ensureIndex ({имя : 1, тип: 1, endMS: -1})

для быстрого доступа.

Теперь я пытаюсь ладить только с одним индексом:

db.games.ensureIndex ({имя: 1, endMS: -1, тип: 1})

первый запрос или курс все еще отлично. Идея второго запроса заключается в том, что Mongo может потребоваться пропустить некоторые записи при сканировании индекса, но только нужно получить доступ к документам, которые, наконец, будут возвращены запросом, потому что «тип» уже может быть проверен в индексе. Это должно быть достаточно быстро для моих нужд.

Однако, используя объяснение(), MongoDB сообщает мне, что при запросе базы данных необходимо «scanAndOrder».

db.games.find ({имя: "Стефан", тип: "л", endMS: {$ Gt: 0}}) рода.. ({EndMS: -1}) объясняет()

{ 
    "cursor" : "BtreeCursor name_1_endMS_-1_type_1", 
    "isMultiKey" : false, 
    "n" : 1, 
    "nscannedObjects" : 1, 
    "nscanned" : 22, 
    "nscannedObjectsAllPlans" : 4, 
    "nscannedAllPlans" : 25, 
    "scanAndOrder" : true, 
    "indexOnly" : false, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "millis" : 0, 
    "indexBounds" : { 
     "name" : [ 
      [ 
       "Stefan", 
       "Stefan" 
      ] 
     ], 
     "endMS" : [ 
      [ 
       Infinity, 
       0 
      ] 
     ], 
     "type" : [ 
      [ 
       "bli", 
       "bli" 
      ] 
     ] 
    }, 
    "server" : "localhost:27017", 
    "filterSet" : false 
} 

nscannedObjects и nscanned являются, как и ожидалось, как описано выше, но мне интересно, почему Монго говорит scanAndOrder: верно.

В соответствии с документами: «scanAndOrder - это логическое значение, которое истинно, когда запрос не может использовать порядок документов в индексе для возврата отсортированных результатов: MongoDB должен сортировать документы после получения документов с помощью курсора».

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

Так почему MongoDB использует scanAndOrder здесь?

+0

В какой версии MongoDB вы используете? Странно, что у вас есть истинный «scanAndOrder» и ложный «indexOnly». Я бы сказал, что ваш запрос включен в индекс ... – rubenfa

+0

Я использую MongoDB 2.6.0-rc0. Поиск не может быть indexOnly, потому что он возвращает весь документ. Это только «indexOnly» в том смысле, что ему не нужно сканировать документ, чтобы узнать, соответствует ли он запросу. – StefanMK

+0

Странно, я добавил {_id: 0, name: 1} в качестве параметра проецирования к запросу, и это также не сделает запрос indexOnly. Возможно, что-то такое, что «тип» на самом деле «tc.type», поэтому он взят из встроенного документа (я просто хотел сделать проблему более понятной здесь). Я помню, что в структуре агрегации MongoDB существует проблема с coverIndexes, когда одна часть индекса поступает из встроенного документа. Но это также влияет на scanAndOrder? – StefanMK

ответ

3

Это, кажется, ошибка в MongoDB 2.6.0-rc0. Все работает как ожидается в MongoDB 2.4.9.

-2

http://docs.mongodb.org/manual/reference/glossary/

естественный порядок: Порядок что а база данных хранит документы на диске. Как правило, порядок документов на дисках отражает порядок вставки, за исключением случаев, когда документ перемещается изнутри, потому что операция обновления увеличивает его размер. В закрытых коллекциях порядок вставки и естественный порядок идентичны, потому что документы не перемещаются внутри страны. MongoDB возвращает документы в прямом естественном порядке для запроса find() без параметров. MongoDB возвращает документы в обратном естественном порядке для запроса find(), отсортированного с параметром $ natural: -1. См. $ Natural.

Ваше предположение о порядке ввода == неверный порядок индексирования.

+0

Это не мое предположение. Я предполагаю, что документы упорядочены по endMS, потому что endMS является второй частью составного индекса. – StefanMK

+0

Там вы идете, вы ответили на свой вопрос. Это ошибка :). Я всегда использую сортировку, если ожидаю определенного порядка, чтобы быть уверенным, и оптимизировать другие области, если производительность не соответствует номиналу. – user2833162

0

Stefan сообщил об ошибке здесь: http://jira.mongodb.org/browse/SERVER-12935 и проблема scanAndOrder была решена после 2.6.0-rc0, но есть некоторые затяжные проблемы с выходом объяснения.