Un ou deux index?

11

J'ai l'index suivant créé sur une table dans ma base de données:

CREATE INDEX [idx_index1]
on [table1]
(col1, col2, col3)

Le serveur suggère l'index «manquant» suivant:

CREATE INDEX [idx_index2]
on [table1]
(col1, col2)
INCLUDE (col3, col4, col5, col6....)

Il me semble logique de modifier la définition d'index existante pour inclure les colonnes suggérées, plutôt que de créer un nouvel index qui doit être maintenu. Une requête qui sélectionne sur col1 et col2 pourrait utiliser index1 tout aussi efficacement que index2. Ai-je raison ou ai-je raté quelque chose?

paulH
la source

Réponses:

12

C'est ainsi que l'art des stratégies de réglage et d'indexation des performances entre en scène ...

Il me semble logique de modifier la définition d'index existante pour y inclure les colonnes suggérées

Je vais prendre votre citation et écrire une troisième définition d'index:

create index [idx_index3]
on [table1] (col1, col2, col3)
include (col4, col5, col6....);

Cela devrait être la CREATE INDEXdéclaration qui correspond à votre déclaration citée.

Cela peut très bien être une solution prudente, mais cela dépend . Voici quelques exemples lorsque je dis que cela dépend.

Si vous avez une charge de travail commune composée principalement de requêtes comme celle-ci:

select col1, col2, col3
from table1
where col1 = 1
and col2 = 2
and col3 = 3;

Votre idx_index1index serait alors solide. Parfaitement étroit, c'est un index qui satisfait cette requête sans aucune donnée étrangère (sans prendre en compte la définition d'index clusterisé, le cas échéant).

Mais si vous avez une charge de travail composée de requêtes comme celle-ci:

select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2;

Ce idx_index2serait alors sage, car c'est ce qu'on appelle un index de couverture, ce qui évite d'avoir à rechercher une clé vers l'index cluster (ou une recherche RID vers le tas). Cette définition d'index non cluster engloberait uniquement toutes les données dont la requête a besoin.

Avec votre recommandation, elle conviendrait parfaitement à une requête comme celle-ci:

select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2
and col3 = 3;

Votre idx_index3recommandation serait un index de couverture qui répond aux critères de recherche pour la requête ci-dessus.

Le point sur lequel j'essaie d'arriver est dans une question isolée comme celle-ci, nous ne pouvons pas y répondre définitivement. Tout dépend de la charge de travail courante et fréquente. Bien sûr, vous pouvez toujours définir ces trois index pour gérer chaque exemple de type de requête, mais cela remet en question la maintenance qui sera nécessaire pour maintenir ces index à jour (pensez: INSERTs, UPDATEs, DELETEs). C'est la surcharge des index.

Vous devez disséquer et évaluer la charge de travail et déterminer où les avantages seront les meilleurs. Si le premier exemple de requête est de loin le plus couramment exécuté des dizaines de fois par seconde, et qu'il existe une requête très rare comme le troisième exemple de requête, il ne serait pas logique de gonfler les pages de niveau feuille de l'index avec le INCLUDEcolonnes non clés. Tout dépend de votre charge de travail.

Si vous comprenez des stratégies d'indexation prudentes et que vous comprenez votre charge de travail commune, alors en appliquant les deux, vous pourrez trouver la meilleure voie à suivre.

Thomas Stringer
la source
Je vais devoir digérer cela pendant un certain temps, mais cela semble être une bonne réponse. Je suppose que c'était une faute de frappe que «index3» que vous avez défini a col3 comme colonne d'égalité ET une colonne incluse?
paulH
Oui :-) Bonne prise. J'ai édité ça.
Thomas Stringer
Sans oublier que si le tableau n'a que les cols 1-6, il est assez idiot d'indexer 1 et 2 et d'inclure 3-5.
Kenneth Fisher
1
@KennethFisher - pourquoi serait-ce idiot? Cela semble une chose assez raisonnable à faire si votre structure de base de données et votre charge de travail le justifient. Par exemple, si vous avez une requête qui sélectionne les colonnes 1 à 5 en fonction des valeurs des colonnes 1 et 2, et peut-être que la colonne 6 est une colonne nvarchar (max) avec laquelle vous ne voulez pas gonfler votre index.
paulH
1
@paulH C'est probablement juste mon opinion mais au moment où vous avez ajouté suffisamment de colonnes pour inclure que votre index a 90 +% de vos colonnes dans la table, vous avez gonflé votre index au point que la lecture supplémentaire pour aller à la table lui-même n'est pas si important. Maintenant, il y a certainement des exceptions .. si les cols 1-5 sont tous des int et que col6 est un varchar (max) alors je pourrais le faire. Mais en général, je les examinerais très attentivement.
Kenneth Fisher
7

Vous avez en effet raison et avez découvert pourquoi il est important pour un DBA de toujours revoir les "suggestions" avancées par les DMV d'index manquants, etc.

Considérez que les suggestions proposées par les DMV d'index manquants sont mises en avant de manière isolée, ce qui signifie que SQL Server a décidé qu'un index de la structure recommandée bénéficierait à la requête, quelles que soient les autres structures d'index pouvant déjà exister.

John Sansom
la source
3

Un peu plus, sur l'une des implications de la réponse de Thomas:

Il a dit:

Bien sûr, vous pouvez toujours définir ces trois index pour gérer chaque exemple de type de requête, mais cela remet en question la maintenance qui sera nécessaire pour maintenir ces index à jour (pensez: INSERTs, UPDATEs, DELETEs). C'est la surcharge des index.

Donc, une autre grande question devient: à quelle fréquence le tableau est-il mis à jour?

Considérons d'abord un exemple de table constamment mise à jour, comme par exemple une ORDERStable de vente au détail reflétant l'activité des consommateurs de sites Web ... là, vous voulez être consciencieux d'avoir plusieurs index, car ils augmentent le travail effectué par des mises à jour constantes, et donc affecter en permanence les performances de la base de données.

D'un autre côté, considérez un tableau qui n'est mis à jour que dans le cadre de la configuration du site Web - le tableau étant mis à jour UNE FOIS pour la plupart des valeurs, et des valeurs rarement ajoutées -, les ralentissements de mise à jour ne sont pratiquement pas pris en compte. Plusieurs index pourraient ralentir les reconstructions et réorganisations d'index de base de données, mais tant qu'ils sont suffisamment rapides, N'HÉSITEZ PAS: si plusieurs index accélèrent les lectures, allez-y.

Un cas intermédiaire pourrait être une table qui n'est normalement mise à jour dans un processus par lots que pendant la nuit. Là, les ralentissements de mise à jour à partir de plusieurs index n'affecteraient pas les performances de jour - ils n'affecteraient que (1) le temps nécessaire pour exécuter cette maintenance par lots de nuit, (2) les performances de tous les processus simultanés et (3) le temps nécessaire pour tâches de maintenance de base de données comme la réorganisation d'index. Donc, tant que les processus dans ces 3 arènes fonctionnent assez vite pour vous ... créez les index qui accélèrent les requêtes.

HTH ...

Doug_Ivison
la source