Почему мой запрос на mongodb такой медленный?
Я установил свою геопространственную коллекцию — я выполняю несколько действительно великолепных запросов, чтобы убедиться, что места, которые я извлекаю, не находятся в каком-либо кеше, и я просто поражен тем, как быстро возвращаются данные.
Проблема заключается в том, что когда я запрашиваю коллекцию для получения необходимых данных lon / lat по имени: город и штат или город и страна, кажется, что выполнение запроса занимает несколько секунд !
Я правильно настроил таблицу … Я проиндексировал дерьмо из всех своих столбцов … Неделю или две назад я был на mongoSV 2011 в Санта-Кларе и узнал некоторые действительно интересные вещи о запросах, индексации и управлении производительностью, так что давайте выкопайте заметки и посмотрите, где я ошибся. Потому что я сильно сомневаюсь, что проблема в Монго, но, скорее, как мы говорили в технической поддержке: это проблема PBCK …
Первое, что я хочу сделать, это запустить объяснение для моего запроса, чтобы я мог видеть план запроса mongo для моего запроса. Это должно дать мне отправную точку для попытки выяснить, что пошло не так.
> db.geodata_geo.find({ cityName : “Anniston”, stateName : “Alabama” }).explain();
Добавляя завершающую функцию: .explain () , я прошу mongoDB вернуть мне план запроса вместо выполнения запроса. Я нажимаю Enter, чтобы запустить объяснение () и получить следующий вывод:
> db.geodata_geo.find({ cityName : “Anniston”, stateName : “Alabama”}).explain(); { “cursor” : “BasicCursor“, “nscanned” : 3691723, “nscannedObjects” : 3691723, “n” : 1, “millis” : 2269, “nYields” : 0, “nChunkSkips” : 0, “isMultiKey” : false, “indexOnly” : false, “indexBounds” : { } }
Важную информацию я выделил жирным шрифтом в выводе запроса (выше). Этот вывод говорит мне о том, что я использовал «BasicCursor» для своего поискового курсора, что указывает на то, что да, я выполняю сканирование таблицы в коллекции. Итак, я уже знаю, что мой запрос не оптимален. Но ждать! Еще хорошие новости …
Значение для nscanned и nscannedObjects одинаково: 3 691 723 — что совпадает с количеством элементов коллекции. Это число — количество документов, отсканированных для выполнения запроса, которое, учитывая его значение, подтверждает, что я выполняю полное сканирование таблицы.
millis сообщает мне количество миллисекунд, на которое запрос может занять: 2,269 секунды: это слишком медленно для моих внутренних методов (), обслуживающих REST API, — недопустимо.
И затем мы переходим к сообщению: IndexOnly сообщает мне, что если бы запрос мог быть решен с помощью (существующего) покрывающего индекса. Когда я вижу значение false, это говорит о том, что в коллекции нет индекса по столбцам, которые я сканирую.
Какая?!? Я знаю, что проиндексировал эту коллекцию …
Итак, я запускаю db.geodata_geo.getIndexes (), чтобы вывести мои индексы и … я … не вижу, что мои столбцы имен проиндексированы. О, я не забыла индексировать столбцы ID и Code … но каким-то образом индексирование столбцов Name полностью ускользнуло от моего нижнего уровня.
Я добавляю эти индексы в свою коллекцию:
> db.geodata_geo.ensureIndex({ cityName : 1 }); > db.geodata_geo.ensureIndex({ stateName : 1 });
И тогда я повторно запускаю план запроса и вижу следующий вывод:
> db.geodata_geo.find({ cityName : “Anniston”, stateName : “Alabama”}).explain(); { “cursor” : “BtreeCursor cityName_1″, “nscanned” : 2, “nscannedObjects” : 2, “n” : 1, “millis” : 101, “nYields” : 0, “nChunkSkips” : 0, “isMultiKey” : false, “indexOnly” : false, “indexBounds” : { “cityName” : [ [ "Anniston", "Anniston" ] ] } }
Вместо BasicCursor я вижу BtreeCursor, который приносит мне счастье. Я также вижу, что значения nscanned и nscannedObjects теперь более реалистичны … серьезно: 2 много лучше, чем 3,6 миллиона, верно? Еще один рад за меня!
Я оцениваю третье счастье, когда вижу, что миллис снизился до 101: 0,101 секунды, чтобы выполнить этот поиск / запрос! Я не согласен, я согласен — но приемлемо, учитывая, что все работает на моем ноутбуке … Я знаю, что время производства будет намного, намного ниже.
В конце концов, я узнал, что простой инструмент, такой как .explain (), может сказать мне, где требуется мое внимание, когда речь идет об оптимизации и исправлении даже простых, казалось бы, невинных запросов. Знание того, на что ты смотришь, и того, что ты ищешь, в значительной степени является бейсбольной битой, когда дело доходит до того, чтобы раздавить одного из парка.
Надеюсь, это поможет!
Источник: http://shallop.com/2011/12/why-is-my-mongo-query-so-slow/