MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

MongoDB Regex, индекс и производителност

MongoDB поддържа регулярни изрази с помощта на оператора $regex. Въпреки това тези заявки за регулярни изрази в MongoDB имат недостатък, всички освен един тип регулярни изрази използват лошо индексите и водят до проблеми с производителността. За производствен сървър с големи количества данни, лошата заявка за регулярни изрази може да постави сървъра ви на колене.

Заявките, базирани на MongoDB, са доста често срещана заявка в повечето приложения, използващи MongoDB. Това е подобно на операцията „LIKE“, поддържана в повечето релационни бази данни. Синтаксисът на командата е както следва

{ $regex: /pattern/, $options: '<options>' }
E.g. { name: { $regex: /^acme.*test/}}

За по-подробна информация относно операцията с регулярни изрази и допълнителни опции вижте документацията на MongoDB

За останалата част от тази дискусия ще приемем, че полето, с което съпоставяте, има индекс. Ако не индексирате, това ще доведе до сканиране на колекция и много лошо представяне. Въпреки това, дори ако полето е индексирано, това може да доведе до лоша производителност. Причината е, че MongoDB може да използва добре индексите само ако вашият регулярен израз е „префиксен израз“ – това са изрази, започващи със знака „^“.

напр. { име: { $regex: /^acme/}

Това позволява на MongoDB да идентифицира диапазон от записи в индекса, които са от значение за тази заявка, и води до ефективни заявки. Всяка друга заявка води до сканиране на индекс, тъй като MongoDB не може да стесни сканирането до диапазон от записи в индекса. Сканирането на индекса е особено лошо, тъй като всички индекси трябва да бъдат страници в паметта и това се отразява на работния набор на вашия сървър (Всъщност сканирането на индекса може да доведе до по-лоша производителност от сканирането на колекция - води до два пъти по-голям брой грешки в страницата ).

Нека разгледаме някои примери и получените планове за заявка. За целите ни на тестване настроих колекция със 100 000 документи. Всеки документ има поле firstName, което е низ от 16 символа.

Пример 1: { име:{ $regex:/^acme/}
Резултат:Ефективно използване на индекса
План на заявката:

executionStats" : {
       "executionSuccess" : true,
       "nReturned" : 0,
       "executionTimeMillis" : 0,
       "totalKeysExamined" : 1,
       "totalDocsExamined" : 0,

Пример 2: { име:{ $regex:/^acme/i}}
Резултат:Неефективно сканиране на индекса поради изискване за независимо от главните букви. Така че по принцип опцията /i отрича „префиксния израз“
План на заявката:

        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 0,
                "executionTimeMillis" : 137,
                "totalKeysExamined" : 100000,
                "totalDocsExamined" : 0,

Пример 3: { име:{ $regex:/acme.*corp/}
Резултат:Неефективно сканиране на индекса
План на заявката:

                "executionSuccess" : true,
                "nReturned" : 0,
                "executionTimeMillis" : 167,
                "totalKeysExamined" : 100000,
                "totalDocsExamined" : 0,

Пример 4: { име:{ $regex:/acme/}}
Резултат:Неефективно сканиране на индекс

        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 0,
                "executionTimeMillis" : 130,
                "totalKeysExamined" : 100000,
                "totalDocsExamined" : 0,

  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Достатъчно бърз и надежден ли е GridFS за производство?

  2. Анализиране на бавни заявки в MongoDB

  3. MongoDB $slice

  4. mongodb версия 3.0.0 клиент robomongo mongovue

  5. Кога да Redis? Кога да MongoDB?