[Tutoriel] MongoDB : Indexation et performance

Suite de notre série d’articles pour vous faire découvrir MongoDB. Après nos tutoriels « Examiner les fonctionnalités de requêtages » et « Insérer, supprimer et mettre à jour des documents« , nous allons examiner aujourd’hui les mécanismes d’indexation et le suivi de performance.

[Tutoriel] MongoDB : Indexation et performance

 

Positionnement de MongoDB par rapport à Hadoop

 

Je croise régulièrement des personnes qui sont convaincues de pouvoir traiter tous les cas d’usage avec une plateforme Hadoop. Il est parfois difficile d’expliquer que derrière le Big Data se cache différents besoins et que Hadoop ne sera pas toujours la solution la plus appropriée pour les résoudre.

Si Hadoop reste la solution la plus pertinente pour faire des analyses de tendance sur un historique profond de données, Hadoop est peu adapté à la recherche et la mise à jour d’enregistrements de détail comme la gestion d’un référentiel client.

 

Pourquoi cela ?

Parce que Hadoop travaille sur des fichiers volumineux, sans index, avec des accès en lecture seule.

Ainsi, si j’ai besoin de mettre à jour une fiche client, je vais devoir rechercher dans mon fichier de 25 millions de clients l’enregistrement correspondant (ça va prendre un peu de temps), modifier l’enregistrement en mémoire puis réécrire tout mon fichier client avec la modification (encore un peu de temps), supprimer l’ancien fichier client et renommer le nouveau (Ouf, c’est terminé mais avouez qu’on peut imaginer plus simple comme opération !).

Les bases NoSQL comme MongoDB ont été crées pour répondre à ces problématiques de manière beaucoup plus efficaces. Nous avons déjà vu dans les précédents tutos comment rechercher, insérer, modifier ou supprimer des documents. Nous allons voir aujourd’hui comment faire cela rapidement avec des index.

 

Création et suppression d’un index

 

Nous allons travailler sur une base exemple contenant les mails de la société Enron.
La collection messages contient plus de 120 000 documents.

[Tutoriel] MongoDB : Indexation et performance - Premiers pas zeppelin

 

 

Chaque document contient les informations typiques que l’on retrouve dans un email (expéditeur, destinataires, date, objet, message, etc.).

[Tutoriel] MongoDB : Indexation et performance - enron-message2

 

Afin de déterminer les index existant, on peut faire appel à la fonction getIndexes() qui va lister les index présents.

[Tutoriel] MongoDB : Indexation et performance - enron-getIndexes-3

 

 

 

 

 

 

 

 

 

Ici, on voit que la collection contient un index sur le champ id. En fait, c’est un index créé par défaut par le système sur l’identifiant des collections afin d’accélérer les recherches.

Pour créer un index spécifique, on utilise la fonction createIndex(). Cette fonction prend comme argument un document JSON contenant un ou plusieurs champs avec pour chacun d’eux le sens du tri (1: croissant, -1: décroissant).
Ainsi, si nous voulons créer un index sur le champ date du header, nous procédons de la manière suivante :

[Tutoriel] MongoDB : Indexation et performance - enron-createindex-date4

La création est très rapide car la collection ne contient que 120 000 documents. On vérifie ensuite que l’index est bien créé.

[Tutoriel] MongoDB : Indexation et performance - enron-getIndexes-date5

 

L’index va permettre, comme dans une base de données relationnelle, d’accélérer certaines requêtes (filtres ou tris sur le champ portant l’index). Pour supprimer un index, on utilise la fonction dropIndex(). L’argument doit être un document JSON identique au document ayant servi à créer l’index.

[Tutoriel] MongoDB : Indexation et performance - enron-dropIndex6

 

Evaluation de la performance

 

Lançons une requête sur notre collection avec un filtre sur l’expéditeur.

[Tutoriel] MongoDB : Indexation et performance - enron-find-7

 

Le nombre de mails envoyés par “rhonda.denton@enron.com” est de 432.

[Tutoriel] MongoDB : Indexation et performance - enron-count-rhonda8

Cette requête filtre les documents de la collection puis comptabilise le nombre total de documents. MongoDB nous permet d’évaluer la performance de cette requête avec la fonction explain(). Sans argument, la fonction renvoie le plan de requête qui va être exécuté. Avec true comme argument, la fonction renvoie également des informations sur l’exécution de la requête.

A noter que la fonction explain se place juste après le nom de la collection et avant les fonctions de find et count.

[Tutoriel] MongoDB : Indexation et performance - enron-explain-query9

 

Dans cette première partie, le winning plan nous indique que la requête est composée de 2 étapes (stages). La première étape fait un scan de la collection pour filtrer les documents satisfaisant le prédicat. La deuxième étape fait un comptage des documents.

[Tutoriel] MongoDB : Indexation et performance - enron-explain-execution10

 

Dans cette deuxième partie du explain, des informations plus précises sur l’exécution de la requête sont données. On peut ainsi constater que 120 477 documents sont examinés et que la durée de requête est estimée à 90 ms.

Nous allons maintenant créer un index sur le champ « headers.From » puis lancer de nouveau un explain pour voir les différences avec la requête sans index.

[Tutoriel] MongoDB : Indexation et performance - enron-createIndex-from11

[Tutoriel] MongoDB : Indexation et performance - enron-explain-query-index12

 

Le winning plan est ici légèrement différent. Il est mentionné l’utilisation de l’index que nous venons de créer (en même temps, c’était notre objectif). Voyons maintenant l’impact sur les temps d’exécution.

[Tutoriel] MongoDB : Indexation et performance - enron-explain-execution-index13

 

Cette fois-ci, la requête n’a plus besoin de scanner toute la collection : seules 433 clés correspondant aux documents de rhonda ont été examinées. La recherche a été fortement accélérée puisque la durée d’exécution de la requête est estimée à 0 ms.

 

Encore plus d’index

 

Il faudrait bien plus qu’un article pour couvrir le sujet des index. Il est possible de créer plusieurs index sur des champs distincts mais aussi des index multiples sur plusieurs champs. La force de MongoDB est aussi de pouvoir proposer des index de type spécifique.

Avec des index de type text, on peut ainsi faire de la recherche full texte dans un ou plusieurs champs. Je commence par créer un index de type text sur le champ « body » de ma collection. La création de l’index va prendre quelques dizaines de secondes car il y a pas mal de matière à indexer.

[Tutoriel] MongoDB : Indexation et performance - enron-index-text14

 

Je fais ensuite une recherche sur « Trump » .

[Tutoriel] MongoDB : Indexation et performance - enron-trump15

 

On trouve 77 documents. Le résultat s’est affiché très rapidement. On va faire un explain pour analyser plus en détail ce qui s’est passé.

[Tutoriel] MongoDB : Indexation et performance - enron-trump-query16

 

Le winning plan montre bien l’utilisation de notre super index.

[Tutoriel] MongoDB : Indexation et performance - enron-trump-execution17

Le résultat d’exécution précise que la requête a récupéré directement les documents concernés grâce à l’index et que cela n’a pris qu’1 ms. Effectivement, c’était rapide 🙂

Parmi les index spécifiques, on trouve également les index de type géospatial :

  • en 2D pour se repérer sur une carte
  • en 3D pour se repérer sur une sphère avec les coordonnées GPS

Je vous invite à consulter la documentation MongoDB pour aller plus loin sur ce sujet.

C’est terminé pour aujourd’hui. Dans un prochain article, nous étudierons les possibilités d’agrégation avec MongoDB.

 

  • A propos
  • Derniers articles

One Comment

  1. Bonjour Stéphane, super article !
    Les indexes sont un élément essentiel et différentiateur de MongoDB.

    certaines copies d’écran sont malheureusement trop comprimées pour être lisibles, c’est dommage.

Laissez un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*