MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

MongoDB Regex, Índice e Desempenho


O MongoDB suporta expressões regulares usando o operador $regex. No entanto, essas consultas de regex do MongoDB têm uma desvantagem, todos, exceto um tipo de regex, fazem mau uso de índices e resultam em problemas de desempenho. Para um servidor de produção com grandes quantidades de dados, uma consulta regex ruim pode deixar seu servidor de joelhos.



As consultas baseadas em regex do MongoDB são bastante comuns na maioria dos aplicativos que usam o MongoDB. Isso é semelhante à operação 'LIKE' suportada na maioria dos bancos de dados relacionais. A sintaxe do comando é a seguinte
{ $regex: /pattern/, $options: '<options>' }
E.g. { name: { $regex: /^acme.*test/}}

Para obter informações mais detalhadas sobre a operação regex e opções adicionais, consulte a documentação do MongoDB

Para o restante desta discussão, vamos supor que o campo com o qual você está correspondendo tem um índice. Se você não indexar, isso resultará em uma verificação de coleção e um desempenho muito ruim. No entanto, mesmo que o campo esteja indexado, isso pode resultar em um desempenho ruim. A razão é que o MongoDB pode fazer bom uso de índices apenas se sua expressão regular for uma “expressão de prefixo” – são expressões que começam com o caractere “^”.

Por exemplo. { name: { $regex: /^acme/}}

Isso permite que o MongoDB identifique um intervalo de entradas de índice relevantes para essa consulta e resulte em consultas eficientes. Qualquer outra consulta resulta em uma verificação de índice, pois o MongoDB não pode restringir a verificação a um intervalo de entradas de índice. Uma verificação de índice é particularmente ruim, pois todos os índices precisam ser paginados na memória e isso afeta o conjunto de trabalho do seu servidor (na verdade, a verificação de índice pode levar a um desempenho pior do que uma verificação de coleção - resulta em duas vezes o número de falhas de página ).

Vejamos alguns exemplos e os planos de consulta resultantes. Para nossos propósitos de teste, configurei uma coleção com 100 mil documentos. Cada documento tem um campo firstName que é uma cadeia de 16 caracteres.

Exemplo 1: { name:{ $regex:/^acme/}}
Resultado:Uso eficiente do índice
Plano de consulta:
executionStats" : {
       "executionSuccess" : true,
       "nReturned" : 0,
       "executionTimeMillis" : 0,
       "totalKeysExamined" : 1,
       "totalDocsExamined" : 0,

Exemplo 2: { nome:{ $regex:/^acme/i}}
Resultado:Varredura de índice ineficiente devido ao requisito que não diferencia maiúsculas de minúsculas. Então, basicamente, a opção /i nega a “expressão de prefixo”
Plano de consulta:
        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 0,
                "executionTimeMillis" : 137,
                "totalKeysExamined" : 100000,
                "totalDocsExamined" : 0,

Exemplo 3: { name:{ $regex:/acme.*corp/}}
Resultado:Verificação de índice ineficiente
Plano de consulta:
                "executionSuccess" : true,
                "nReturned" : 0,
                "executionTimeMillis" : 167,
                "totalKeysExamined" : 100000,
                "totalDocsExamined" : 0,

Exemplo 4: { name:{ $regex:/acme/}}
Resultado:Verificação de índice ineficiente
        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 0,
                "executionTimeMillis" : 130,
                "totalKeysExamined" : 100000,
                "totalDocsExamined" : 0,