web-dev-qa-db-fra.com

Pourquoi la direction de l'index est-elle importante dans MongoDB?

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)?

103
johndodo

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

98
Jared Kells

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}

42
Zaid Masud

Pourquoi les index

Comprenez deux points clés.

  1. Alors qu'un indice vaut mieux qu'aucun indice, l'indice correct est bien meilleur que l'un ou l'autre.
  2. MongoDB n'utilisera qu'un seul index par requête, créant des index composés avec un champ approprié ordonnant ce que vous voulez probablement utiliser.

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.

Comment les 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.

Pourquoi trier

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.

Comment trier

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 }
10
Somnath Muluk