Вашият наблюдаван проблем с производителността при първоначална заявка вероятно е един от следните проблеми (в груб ред на вероятност):
1) Вашето приложение/уеб услуга има някои допълнителни разходи за инициализиране при първа заявка (т.е. разпределяне на памет, настройка на пулове за връзка, разрешаване на DNS, ...).
2) Индексите или данните, които сте поискали, все още не са в паметта, така че трябва да бъдат заредени.
3) Оптимизатор на заявки може да отнеме малко повече време за изпълнение на първата заявка, тъй като сравнява изпълнението на плана за вашия модел на заявка.
Би било много полезно да тествате заявката чрез mongo
обвивка и изолирайте дали режийните разходи са свързани с MongoDB или вашата уеб услуга (вместо да определяте времето и на двете, както сте направили).
Следват някои бележки, свързани с MongoDB.
Кеширане
MongoDB няма време за „кеширане“ за документи в паметта. Той използва картографирани в паметта файлове за I/O на диска и документите в паметта се основават на вашите активни заявки (документи/индекси, които наскоро сте заредили), както и наличната памет. Диспечерът на виртуалната памет на операционната система отговаря за кеширането , и обикновено ще следва алгоритъм за най-малко използвани (LRU), за да реши кои страници да измести от паметта.
Използване на памет
Очакваното поведение е, че с течение на времето MongoDB ще нарасне, за да използва цялата свободна памет за съхраняване на вашия активен работен набор от данни.
Разглеждане на предоставения от вас db.stats()
числа (и ако приемем, че това е единственото ви база данни), изглежда, че размерът на вашата база данни в момента е около 1 Gb, така че трябва да можете да запазите всичко в рамките на общо 10 Gb RAM, освен ако:
- има други процеси, конкуриращи се за памет
- рестартирахте своя
mongod
сървър и тези документи/индекси все още не са заявени
В MongoDB 2.2 има нов touch
команда, която можете да използвате за зареждане на индекси или документи в паметта след рестартиране на сървъра. Това трябва да се използва само при първоначално стартиране за „загряване“ на сървъра, тъй като в противен случай може безполезно да изтласкате действителните „активни“ данни от паметта.
В система Linux, например, можете да използвате top
и трябва да видите това:
- виртуалните байтове/VSIZE обикновено са с размера на цялата база данни
- ако сървърът няма други работещи процеси, резидентните байтове/RSIZE ще бъдат общата памет на машината (това включва съдържанието на кеша на файловата система)
mongod
не трябва да използва swap (тъй като файловете са картирани в паметта)
Можете да използвате mongostat
инструмент за бърз преглед на вашия mongod
дейност .. или по-полезно, използвайте услуга като MMS
за наблюдение на показателите във времето.
Оптимизатор на заявки
MongoDB Оптимизатор на заявки
сравнява изпълнението на плана за модел на заявка на всеки ~1000 операции за запис и след това кешира "печелившия" план на заявка до следващия път, когато оптимизаторът се изпълни .. или изрично извиквате explain()
на тази заявка.
Това трябва да е лесно за тестване:изпълнете заявката си в mongo
обвивка с .explain()
и погледнете времената на ms, а също и броя на записите в индекса и сканираните документи. Времето за обяснение() не е действителното време, което ще отнеме изпълнението на заявките, тъй като включва разходите за сравняване на плановете. Типичното изпълнение ще бъде много по-бързо .. и можете да търсите бавни заявки във вашия mongod
дневник.
По подразбиране MongoDB ще регистрира всички заявки, по-бавни от 100ms, така че това осигурява добра отправна точка за търсене на заявки за оптимизиране. Можете да регулирате бавната стойност на ms с --slowms
опция за конфигурация или използване на Database Profiler
команди.
Допълнителна информация в документацията на MongoDB:
- Кеширане
- Проверка на използването на паметта на сървъра
- Профил на база данни
- Обяснете
- Наблюдение и диагностика