Étant donné une requête standard simple (sans limit()
ou sort()
ou quelque chose de fantaisie appliqué) qui a une condition de filtre sur deux champs (comme dans name
et age
dans votre exemple), afin de trouver les documents résultants, MongoDB va soit :
- faire une analyse complète de la collection (lire chaque document de l'ensemble de la collection, analyser le BSON, trouver les valeurs en question, les tester par rapport à l'entrée et renvoyer/supprimer chaque document) :C'est une activité intense en E/S et donc lente.
- utiliser un seul index qui contient l'un des champs (utilisez l'arborescence d'index pour localiser le sous-ensemble pertinent de documents suivi d'une analyse de ceux-ci) :en fonction de la distribution de vos données/de la sélectivité de l'index, cela peut être très rapide ou ne fournir que peu d'avantages (imaginez un index sur
age
dans un ensemble de données de millions de personnes entre 30 et 40 ans --> chaque recherche produirait toujours un nombre infini de documents). - utiliser deux index qui contiennent ensemble les deux champs en question (chargez les deux index, effectuez des recherches de clé, puis calculez l'intersection des résultats) :Encore une fois, en fonction de la distribution de vos données, cela peut ou non vous donner de meilleures performances. Il devrait, cependant, dans la plupart des cas être plus rapide que #2. Cependant, je serais surpris si c'était vraiment 10 fois plus lent que le #4 (comme vous l'avez mentionné).
- utiliser un index composé (deux recherches de clé ultérieures conduisent immédiatement aux documents requis) :ce sera l'option la plus rapide de toutes étant donné qu'elle nécessite le moins d'opérations et la moins chère pour accéder aux bons documents. Afin d'assurer le plus haut niveau de réutilisation (pas de performances qui ne seront pas affectées par cela), vous devriez en général commencer par le champ le plus sélectif en premier, donc dans votre cas probablement
name
et nonage
étant donné que beaucoup de personnes auront le mêmeage
(donc faible sélectivité) par rapport àname
(plus grande sélectivité). Mais ce choix dépend également de votre scénario concret et des requêtes que vous avez l'intention d'exécuter sur votre base de données. Il existe un très bon article sur le Web sur la meilleure façon de définir un index composé en tenant compte de divers aspects de votre situation spécifique :https://emptysqua.re/blog/optimizing-mongodb-compound-indexes
D'autres aspects à considérer sont :Les mises à jour d'index viennent à un certain prix. Cependant, si tout ce qui vous intéresse est la vitesse de lecture brute et que vous n'avez que quelques mises à jour de temps en temps, alors vous devriez opter pour des index plus grands.
Et le dernier mais non le moindre (!) Le conseil de base bien trop utilisé :profilez l'enfer de votre système en utilisant des données réelles et peut-être même des scénarios de charge réalistes. Et continuez également à mesurer à mesure que vos données/système changent au fil du temps.
Lectures supplémentaires :https://docs.mongodb.com/manual/core/query-optimization/index.html
https://dba.stackexchange.com/questions/158240/mongodb-index-intersection-does-not-eliminate-the-need-for-creating-compound-in
Index intersection vs index composé ?
index composé mongodb vs intersection d'index
Quelle est l'importance de l'ordre des index composés dans MongoDB en termes de performances ?
Dans MongoDB, j'utilise une grande requête, comment je vais créer un index composé ou un index unique, donc mon temps de réponse augmente