Pour citer les docs :
Lors de la création d'un index, le nombre associé à une clé spécifie la direction de l'index, il doit donc toujours être 1 (ascendant) ou -1 (descendant). La direction n'a pas d'importance pour les index à clé unique ou pour la récupération d'accès aléatoire, mais elle est importante si vous effectuez des tri ou des requêtes de plage sur des index composés.
Cependant, je ne vois aucune raison pour laquelle la direction de l'indice devrait être importante pour les indices composés. Quelqu'un peut-il fournir une explication supplémentaire (ou un exemple)?
MongoDB concatène la clé composée d'une certaine manière et l'utilise comme clé dans un BTree.
Lors de la recherche d'éléments uniques - L'ordre des nœuds dans l'arborescence n'a pas d'importance.
Si vous retournez une plage de nœuds - Les éléments proches les uns des autres seront dans les mêmes branches de l'arbre. Plus les nœuds sont proches de la plage, plus ils peuvent être récupérés rapidement.
Avec un seul index de champ - L'ordre n'aura pas d'importance. S'ils sont rapprochés dans l'ordre croissant, ils seront également rapprochés dans l'ordre décroissant.
Quand vous avez une clé composée - L'ordre commence à avoir de l'importance.
Par exemple, si la clé est A ascendante B ascendante, l'index pourrait ressembler à ceci:
Ligne AB 1 1 1 2 2 6 3 2 7 4 3 4 5 3 5 6 3 6 7 5 1
Une requête pour A ascendant B descendant devra sauter l'index dans le désordre pour retourner les lignes et sera plus lente. Par exemple, il renverra la ligne 1, 3, 2, 6, 5, 4, 7
Une requête à distance dans le même ordre que l'index renverra simplement les lignes séquentiellement dans le bon ordre.
La recherche d'un enregistrement dans un BTree prend O(Log(n)) temps. La recherche d'une plage d'enregistrements dans l'ordre est uniquement OLog (n) + k où k est le nombre d'enregistrements à renvoyer.
Si les enregistrements sont en panne, le coût peut être aussi élevé que OLog (n) * k
réponse simple que vous recherchez est que la direction n'a d'importance que lorsque vous triez sur deux champs ou plus .
Si vous triez sur {a : 1, b : -1}
:
Index {a : 1, b : 1}
sera plus lent que index {a : 1, b : -1}
Comprenez deux points clés.
Les index ne sont pas gratuits. Ils prennent de la mémoire et imposent une pénalité de performance lors des insertions, des mises à jour et des suppressions. Normalement, les performances sont négligeables (en particulier par rapport aux gains de performances en lecture), mais cela ne signifie pas que nous ne pouvons pas être intelligents dans la création de nos index.
L'identification du groupe de champs à indexer ensemble consiste à comprendre les requêtes que vous exécutez. L'ordre des champs utilisés pour créer votre index est critique. La bonne nouvelle est que, si vous vous trompez de commande, l'index ne sera pas utilisé du tout, il sera donc facile de le repérer avec une explication.
Vos requêtes peuvent nécessiter un tri. Mais le tri peut être une opération coûteuse, il est donc important de traiter les champs que vous triez comme un champ que vous interrogez. Il sera donc plus rapide s'il a un index. Il existe cependant une différence importante, le champ que vous triez doit être le dernier champ de votre index. La seule exception à cette règle est que si le champ fait également partie de votre requête, la règle doit être la dernière ne s'applique pas.
Vous pouvez spécifier un tri sur toutes les clés de l'index ou sur un sous-ensemble; cependant, les clés de tri doivent être répertoriées dans le même ordre qu'elles apparaissent dans l'index. Par exemple, un modèle de clé d'index {a: 1, b: 1} peut prendre en charge un tri sur {a: 1, b: 1} mais pas sur {b: 1, a: 1}.
Le tri doit spécifier le même sens de tri (c'est-à-dire croissant/décroissant) pour toutes ses clés comme modèle de clé d'index ou spécifier le sens de tri inverse pour toutes ses clés comme modèle de clé d'index. Par exemple, un modèle de clé d'index {a: 1, b: 1} peut prendre en charge un tri sur {a: 1, b: 1} et {a: -1, b: -1} mais pas sur {a: -1 , b: 1}.
Supposons qu'il existe ces index:
{ a: 1 }
{ a: 1, b: 1 }
{ a: 1, b: 1, c: 1 }
Example Index Used
db.data.find().sort( { a: 1 } ) { a: 1 }
db.data.find().sort( { a: -1 } ) { a: 1 }
db.data.find().sort( { a: 1, b: 1 } ) { a: 1, b: 1 }
db.data.find().sort( { a: -1, b: -1 } ) { a: 1, b: 1 }
db.data.find().sort( { a: 1, b: 1, c: 1 } ) { a: 1, b: 1, c: 1 }
db.data.find( { a: { $gt: 4 } } ).sort( { a: 1, b: 1 } ) { a: 1, b: 1 }