Производительность MongoDB варьируется - PullRequest
2 голосов
/ 30 ноября 2011

У меня есть такая коллекция монго:


{
"A2_AboutMe": "",
"A2_Attributes": "|av|nv|",
"A2_Birthday": "",
"A2_DateCreated": "2010-11-25 22: 59: 00",
"A2_DateLast": "2011-11-18 12: 09: 36",
"A2_FK_A1_IDPerson": "0",
"A2_Firstname": "José Luis",
"A2_FirstnameC": "Jose Luis",
"A2_Gender": "m",
"A2_IDProfile": "1",
"A2_Keywords": "...|..",
"A2_Lastname": "test - test",
"A2_LastnameC": "_test test",
"A2_Locale": "",
"A2_Middlename": "",
"A2_Name": "José Luis test",
"A2_NameC": "Jose Luis test",
...
}

с индексами на A2_LastnameC и A2_FirstnameC 3.000.000 документов в этой коллекции, 8 ГБ хранилище данных

следующий запрос (PHP) выполняется за 3-4 секунды

$collection->find(array(«A2_FirstnameC» => new MongoRegex("/jose/i")))->sort(array(«A2_LastnameC» => -1))->limit(10)

но иногда подобные запросы выполняются менее чем за 100 мсек.

Что я могу сделать, чтобы получить это представление каждый раз?

тестовый компьютер i7, Ram 8 ГБ (7 используется mongo), Windows 7

Ответы [ 2 ]

0 голосов
/ 30 ноября 2011

Прежде всего, индекс не будет использоваться для регулярных выражений без учета префиксов и без учета регистра. Но в приведенном выше запросе индекс можно использовать для сортировки по полю A2_LastnameC, так что это быстро. Теперь, имея отсортированные данные, MongoDB нужно будет получить значение A2_FirstnameC и сопоставить его с остановкой регулярного выражения, когда будет готово 10 совпадений (это также будет относительно быстро, поскольку он будет использовать индекс для извлечения данных вместо чтения целых документов с диска) , В зависимости от порядка данных это может совпадать с первыми 10 документами - это лучший случай, и он будет очень быстрым, а худший - совпадения на последних 10 документах, при которых нужно сканировать все предыдущие записи индекса.

Как ускорить это? Либо используйте запрос, который может использовать индекс, например: «A2_FirstnameC» => new MongoRegex("/^jose/"). Или вы должны использовать какой-то полнотекстовый поиск. Простым способом было бы разделить поле (A2_Firstname в вашем случае) на слова, нормализовать их (преобразовать в нижний регистр, заменить акценты) и сохранить в виде массива. Теперь индекс для поля массива будет использоваться для быстрого поиска.

0 голосов
/ 30 ноября 2011

Индексы нельзя использовать для запросов регулярного выражения без учета регистра, а также для некорневых регулярных выражений (не начинающихся с "^").Поскольку у вас уже есть поле A2_Firstname, денормализованное как A2_FirstnameC, вы также можете сохранить это поле с нормализацией по регистру (т. Е. Либо со всем нижним, либо со всем верхним регистром) и избежать необходимости использовать регистрозависимые регулярные выражения;однако даже в этом случае вы все равно будете выполнять полное сканирование коллекции, если не используете корневое регулярное выражение.Возможность использования одного из них в этом случае зависит от вашего конкретного случая использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...