четверг, 22 октября 2015 г.

"Best practices" для cоздания индексов в MongoDB

Приведу ряд "best practices" для индексов в MongoDB направленные на улучшение производительности.

Один индекс для каждого запроса.

    MongoDB может использовать только один индекс для любого запроса. Хотя в MongoDB 2.6 появилось пересечение индексов которое позволяет использовать два индекса для выборки, но есть целый ряд нюансов когда пересечение индексов не работает поэтому одиночный и составной индекс остаются более простыми в управлении и оптимизации.


Один “multi-value” оператор для запроса

    Такие операторы как $gt, $gte, $lt and $lte, $in and $nin, $ne, $not and $near позволяют выбирать по диапазону значений.  Если вы нуждаетесь в исползовании таких операторов используйте только один и не больше. Причина в том, что для таких запросов индексы мало эффективны  и  в большинстве случаев MongoDB будет сканировать индекс/колекцию.

“Multi-value” поля последние в индексе. 

    Если вы индексируете несколько полей и по одному из этих полей планируется выполнять выборки используя “Multi-value” операторы которые я упомянул выше то следует это поле поместить в конец индекса. Т.е. поля по которым идет сравнение по точному совпадению должны идти первыми, а затем только поля по которым планируется делать выборки по диапазону.

Переместите логику в схему

    Представте ситуацию что ваше приложение выбирает документы за определенный день. Ваша коллекция содержит поле с датой создания документа и  чтобы найти документы вы пишите
db.coll.find(createDate: { $gte: ISODate('2015-10-20'), $lt: ISODate('2015-10-21') } ) 
Дата больше или равна полуночи интересуемого дня и меньше полуночи следующего дня. Даже имея индекс по полю  createDate запрос будет работать медленно т.к. MongoDB будет выполнять много сканирований индекса. Но это легко оптимизировать. Мы можем создать поле day_bucket и заполнять его текущей датой
db.coll.insert({createDate:ISODate('2015-10-20T11:34:12.556Z'),day_bucket:ISODate("2015-10-20"});
  Любой документ для этой даты будет иметь одинаковое day_bucket значение и чтобы найти все документы за дату достаточно выполнить просто запрос.
db.coll.find(day_bucket:ISODate('2015-10-20)); 
Простой эквивалент делает гораздо меньше сканирований. Используя подобную технику вы можете значительно оптимизировать выборки.

Слишком много индексов.

    Искушение создать индексы для всех возможных выборок может быть велико, но не поддавайтесь этому искушению. Каждый созданный индекс снижает производительность операций вставки и обновления. Если вы имеете коллекцию в которую операции вставки медленны или происходят блокировки базы на длительное время проверьте какие индексы есть в коллекции и убедитесь что вы нуждаетесь в их и что они используются эффективно.

Индексы должны помещаться в RAM.

    Это может казаться очевидным но для лучшей производительности индексов индексы должны помещаться в RAM.  Если индексы не помещаются в RAM MongoDB вынуждена читать индекс с диска что приводит к снижению производительности системы.
    Убедитесь что ваши индексы помещаются в памяти.

Комментариев нет:

Отправить комментарий