Первые параметры на самом деле должны работать довольно хорошо. Согласно $regex
документам :
[...] Дальнейшая оптимизация может произойти, если регулярное выражение является «выражением префикса», что означает, что все потенциальные совпадения начинаются с той же строкой. [...]
Регулярное выражение является «префиксным выражением», если оно начинается с каретки (^) или левого якоря (\ A), за которым следует строка простых символов. [...]
Эксперимент
Давайте проверим, как это работает в коллекции с ~ 800 тыс. Документов, ~ 25% из них имеют электронное письмо. Анализируемый пример запроса: {email: /^gmail/}
.
Без индекса:
db.users.find({email: /^gmail/}).explain('executionStats').executionStats
// ...
// "nReturned" : 2208,
// "executionTimeMillis" : 250,
// "totalKeysExamined" : 0,
// "totalDocsExamined" : 202720,
// ...
С индексом {email: 1}
:
db.users.find({email: /^gmail/}).explain('executionStats').executionStats
// ...
// "nReturned" : 2208,
// "executionTimeMillis" : 5,
// "totalKeysExamined" : 2209,
// "totalDocsExamined" : 2208,
// ...
Как мы видим, это определенно помогает - как с точки зрения времени выполнения, так и проверенных документов (более изученные документы означают, возможно, больше работы ввода-вывода). Давайте посмотрим, как это работает, если мы проигнорируем префикс и будем использовать запрос более непосредственно: {email: /gmail/}
.
Без индекса:
db.users.find({email: /gmail/}).explain('executionStats').executionStats
// ...
// "nReturned" : 2217,
// "executionTimeMillis" : 327,
// "totalKeysExamined" : 0,
// "totalDocsExamined" : 202720,
// ...
С индексом {email: 1}
:
db.users.find({email: /gmail/}).explain('executionStats').executionStats
// ...
// "nReturned" : 2217,
// "executionTimeMillis" : 210,
// "totalKeysExamined" : 200616,
// "totalDocsExamined" : 2217,
// ...
В конце концов, индекс помогает много , особенно при выполнении запроса с префиксом. Похоже, что префиксный запрос достаточно быстрый, чтобы сохранить его в одном поле. Отдельное поле может использовать индекс еще лучше (поиграйте с ним!), Но я думаю, что 5 мс вполне достаточно.
Как всегда, я настоятельно рекомендую вам выполнить тесты на ваши данные и посмотрите, как они работают, так как характеристики c могут повлиять на производительность.