MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

MongoDB Regex, index et performances

MongoDB prend en charge les expressions régulières à l'aide de l'opérateur $regex. Cependant, ces requêtes regex MongoDB ont un inconvénient, tous les types de regex sauf un utilisent mal les index et entraînent des problèmes de performances. Pour un serveur de production avec de grandes quantités de données, une mauvaise requête regex peut mettre votre serveur à genoux.

Les requêtes basées sur MongoDB regex sont une requête assez courante dans la plupart des applications utilisant MongoDB. Ceci est similaire à l'opération "LIKE" prise en charge sur la plupart des bases de données relationnelles. La syntaxe de la commande est la suivante

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

Pour plus d'informations sur l'opération regex et les options supplémentaires, reportez-vous à la documentation MongoDB

Pour le reste de cette discussion, nous supposerons que le champ auquel vous faites correspondre a un index. Si vous n'indexez pas, cela entraînera une analyse de la collection et des performances très médiocres. Cependant, même si le champ est indexé, cela peut entraîner des performances médiocres. La raison en est que MongoDB ne peut faire bon usage des index que si votre expression régulière est une "expression de préfixe" - ce sont des expressions commençant par le caractère "^".

Par exemple. { nom : { $regex : /^acme/}}

Cela permet à MongoDB d'identifier une plage d'entrées d'index pertinentes pour cette requête et d'obtenir des requêtes efficaces. Toute autre requête entraîne une analyse d'index car MongoDB n'est pas en mesure de limiter l'analyse à une plage d'entrées d'index. Une analyse d'index est particulièrement mauvaise car tous les index doivent être paginés en mémoire, ce qui affecte l'ensemble de travail de votre serveur (en fait, l'analyse d'index peut entraîner de moins bonnes performances qu'une analyse de collection - elle entraîne le double du nombre de défauts de page ).

Examinons quelques exemples et les plans de requête qui en résultent. Pour nos besoins de test, j'ai configuré une collection avec 100 000 documents. Chaque document a un champ firstName qui est une chaîne de 16 caractères.

Exemple 1 : { nom :{ $regex :/^acme/}}
Résultat :Utilisation efficace de l'index
Plan de requête :

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

Exemple 2 : { nom :{ $regex :/^acme/i}}
Résultat :analyse d'index inefficace en raison d'une exigence insensible à la casse. Donc, fondamentalement, l'option /i annule l'"expression de préfixe"
Plan de requête :

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

Exemple 3 : { nom :{ $regex :/acme.*corp/}}
Résultat :Analyse d'index inefficace
Plan de requête :

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

Exemple 4 : { nom :{ $regex :/acme/}}
Résultat :Analyse d'index inefficace

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