J'ai entendu dire que vous devriez mettre les colonnes qui seront les plus sélectives au début de la déclaration d'index. Exemple:
CREATE NONCLUSTERED INDEX MyINDX on Table1
(
MostSelective,
SecondMost,
Least
)
Tout d'abord, ce que je dis est-il correct? Si tel est le cas, est-ce que je suis susceptible de voir de grandes différences de performances en réorganisant l'ordre des colonnes dans mon index ou est-ce plutôt une pratique «agréable à faire»?
La raison pour laquelle je pose la question est qu'après avoir mis une requête via le DTA, il m'a recommandé de créer un index contenant presque toutes les mêmes colonnes qu'un index existant, juste dans un ordre différent. J'envisageais simplement d'ajouter les colonnes manquantes à l'index existant et de l'appeler bien. Pensées?
la source
L'ordre des colonnes est critique. Maintenant, quel ordre est correct, cela dépend de la façon dont vous allez l'interroger. Un index peut être utilisé pour effectuer une recherche exacte ou un balayage de plage. Une recherche exacte se produit lorsque les valeurs de toutes les colonnes de l'index sont spécifiées et que la requête arrive exactement sur la ligne concernée. Pour les recherches, l'ordre des colonnes n'est pas pertinent. Une analyse de plage se produit lorsque seules certaines colonnes sont spécifiées et, dans ce cas, lorsque l'ordre devient important. SQL Server peut utiliser un index pour une analyse de plage uniquement si la colonne la plus à gauche est spécifiée, et uniquement si la colonne la plus à gauche suivante est spécifiée, et ainsi de suite. Si vous avez un index sur (A, B, C), il peut être utilisé pour rechercher
A=@a
, pourA=@a AND B=@b
mais pas pourB=@b
, pourC=@c
niB=@b AND C=@c
. Le casA=@a AND C=@c
est mixte, comme dans leA=@a
partie utilisera l'index, maisC=@c
pas (la requête analysera toutes les valeurs B pourA=@a
, ne «sautera» pasC=@c
). D'autres systèmes de base de données ont ce qu'on appelle l'opérateur «skip scan» qui peut tirer parti des colonnes internes d'un index lorsque les colonnes externes ne sont pas spécifiées.Avec ces connaissances en main, vous pouvez revoir les définitions d'index. Un index sur
(MostSelective, SecondMost, Least)
ne sera effectif que lorsque laMostSelective
colonne est spécifiée. Mais cela étant le plus sélectif, la pertinence des colonnes internes se dégradera rapidement. Très souvent, vous constaterez qu'un meilleur index est activé(MostSelective) include (SecondMost, Least)
ou activé(MostSelective, SecondMost) include (Least)
. Parce que les colonnes internes sont moins pertinentes, placer des colonnes à faible sélectivité dans de telles positions correctes dans l'index ne les fait rien d'autre que du bruit pour une recherche, il est donc logique de les déplacer hors des pages intermédiaires et de les conserver uniquement sur les pages feuilles, pour à des fins de couverture des requêtes. En d'autres termes, déplacez-les vers INCLUDE. Cela devient plus important à mesure que la taille de laLeast
colonne augmente. L'idée est que cet index ne peut bénéficier qu'aux requêtes qui spécifientMostSelective
soit comme valeur exacte, soit comme plage, et cette colonne étant la plus sélective, elle restreint déjà dans une large mesure les lignes candidates.D'un autre côté, un index sur
(Least, SecondMost, MostSelective)
peut sembler une erreur, mais c'est en fait un indice assez puissant. Comme il a laLeast
colonne comme requête la plus externe, il peut être utilisé pour les requêtes qui doivent regrouper les résultats sur des colonnes à faible sélectivité. De telles requêtes sont répandues dans les entrepôts de données OLAP et d'analyse, et c'est exactement là que ces index ont de très bons arguments. De tels index constituent en fait d'excellents index clusterisés , précisément parce qu'ils organisent la disposition physique sur de grands morceaux de lignes associées (mêmeLeast
valeur, qui indiquent généralement une sorte de catégorie ou de type) et ils facilitent les requêtes d'analyse.Donc, malheureusement, il n'y a pas d'ordre «correct». Vous ne devez suivre aucune recette de coupe-biscuits, mais plutôt analyser le modèle de requête que vous allez utiliser sur ces tables et décider quel ordre de colonne d'index est le bon.
la source
Comme le dit Remus, cela dépend de votre charge de travail.
Je veux cependant aborder un aspect trompeur de la réponse acceptée.
Pour les requêtes qui exécutent une recherche d'égalité sur toutes les colonnes de l'index, il n'y a pas de différence significative.
Le tableau ci-dessous crée deux tableaux et les remplit avec des données identiques. La seule différence est que l'un a les clés classées du plus au moins sélectif et l'autre l'inverse.
Maintenant, faites une requête sur les deux tables ...
... Les deux utilisent une amende indexée et les deux reçoivent exactement le même coût.
L'art ASCII dans la réponse acceptée n'est en fait pas la façon dont les index sont structurés. Les pages d'index de Table1 sont représentées ci-dessous (cliquez sur l'image pour l'ouvrir en taille réelle).
Les pages d'index contiennent des lignes contenant la clé entière (dans ce cas, il y a en fait une colonne clé supplémentaire ajoutée pour l'identificateur de ligne car l'index n'a pas été déclaré comme unique mais qui peut être ignoré, des informations supplémentaires à ce sujet peuvent être trouvées ici ).
Pour la requête ci-dessus, SQL Server ne se soucie pas de la sélectivité des colonnes. Il effectue une recherche binaire de la page racine et découvre que la clé
(PPP...,3,~ )
est>=(JJJ...,1,~ )
et< (SSS...,3,~ )
doit donc lire la page1:118
. Il effectue ensuite une recherche binaire des entrées clés de cette page et localise la page feuille vers laquelle se déplacer.La modification de l'index par ordre de sélectivité n'affecte ni le nombre attendu de comparaisons clés de la recherche binaire ni le nombre de pages à parcourir pour effectuer une recherche d'index. Au mieux, cela pourrait légèrement accélérer la comparaison clé elle-même.
Parfois, la commande de l'index le plus sélectif en premier aura du sens pour d'autres requêtes de votre charge de travail.
Par exemple, si la charge de travail contient des requêtes des deux formes suivantes.
Les index ci-dessus ne couvrent ni l'un ni l'autre.
MostSelective
est suffisamment sélectif pour faire un plan avec une recherche et des recherches utiles, mais la requête contreLeast
ne l'est pas.Cependant, ce scénario (recherche d'index non couvrant sur un sous-ensemble de colonne (s) de tête d'un index composite) n'est qu'une classe de requête possible qui peut être aidée par un index. Si vous ne recherchez jamais par
MostSelective
lui-même ou par une combinaison deMostSelective, SecondMost
et toujours par une combinaison des trois colonnes, cet avantage théorique vous est inutile.À l'inverse, des requêtes telles que
Serait aidé en ayant l'ordre inverse de celui couramment prescrit - car il couvre la requête, peut prendre en charge une recherche et retourne les lignes dans l'ordre souhaité pour démarrer.
Il s'agit donc d'un conseil souvent répété, mais il s'agit tout au plus d'une heuristique sur les avantages potentiels d' autres requêtes - et cela ne remplace pas le fait d'examiner votre charge de travail.
la source
Correct. Les index peuvent être composites - composés de plusieurs colonnes - et l'ordre est important en raison du principe le plus à gauche. La raison en est que la base de données vérifie la liste de gauche à droite et doit trouver une référence de colonne correspondante correspondant à l'ordre défini. Par exemple, avoir un index sur une table d'adresses avec des colonnes:
Toute requête utilisant la
address
colonne peut utiliser l'index, mais si la requête n'a que des référencescity
et / oustate
, l'index ne peut pas être utilisé. C'est parce que la colonne la plus à gauche n'est pas référencée. Les performances des requêtes doivent vous indiquer ce qui est optimal: des index individuels ou plusieurs composites avec des ordres différents. Bonne lecture: The Tipping Point , par Kimberley Trippla source
Toutes les autres réponses sont fausses.
La sélectivité des colonnes individuelles dans un index composite n'a pas d' importance lors du prélèvement de la commande.
Voici le processus de réflexion simple: En effet, un index est la concaténation des colonnes impliquées.
En donnant cette justification, la seule différence est de comparer deux «chaînes» qui diffèrent plus tôt que plus tard dans la chaîne. C'est une infime partie du coût total. Il n'y a pas de «premier passage / deuxième passage», comme mentionné dans une réponse.
Alors, quel ordre doit être utilisé?
=
, dans n'importe quel ordre.Par exemple, la colonne de très faible sélectivité doit venir en premier dans ceci:
Changer l'ordre dans l'index le ferait totalement ignorer
deleted
.(Il y a beaucoup plus de règles pour classer les colonnes.)
la source
deleted
n'aide pas beaucoup à filtrer les lignes indésirables. Avez-vous un meilleur exemple? (C'est celui qui m'est venu à l'esprit lorsque j'ai écrit la réponse.)