Index multiples vs index multi-colonnes

646

Je viens d'ajouter un index à une table dans SQL Server 2005 et cela m'a fait réfléchir. Quelle est la différence entre créer 1 index et définir plusieurs colonnes par rapport à avoir 1 index par colonne que vous souhaitez indexer.

Y a-t-il certaines raisons pour lesquelles l'une devrait être utilisée par rapport à l'autre?

Par exemple

Create NonClustered Index IX_IndexName On TableName
(Column1 Asc, Column2 Asc, Column3 Asc)

Contre

Create NonClustered Index IX_IndexName1 On TableName
(Column1 Asc)

Create NonClustered Index IX_IndexName2 On TableName
(Column2 Asc)

Create NonClustered Index IX_IndexName3 On TableName
(Column3 Asc)
GateKiller
la source

Réponses:

319

Je suis d'accord avec Cade Roux .

Cet article devrait vous mettre sur la bonne voie:

Une chose à noter, les index clusterisés devraient avoir une clé unique (une colonne d'identité que je recommanderais) comme première colonne. Fondamentalement, cela aide votre insertion de données à la fin de l'index et ne provoque pas beaucoup d'E / S de disque et de fractionnements de page.

Deuxièmement, si vous créez d'autres index sur vos données et qu'ils sont construits intelligemment, ils seront réutilisés.

par exemple, imaginez que vous recherchez un tableau sur trois colonnes

état, comté, zip.

  • vous recherchez parfois par état uniquement.
  • vous recherchez parfois par état et comté.
  • vous effectuez fréquemment des recherches par état, comté, code postal.

Puis un index avec état, comté, zip. sera utilisé dans ces trois recherches.

Si vous recherchez beaucoup par zip seul, alors l'index ci-dessus ne sera pas utilisé (par SQL Server de toute façon) car zip est la troisième partie de cet index et l'optimiseur de requête ne verra pas cet index comme utile.

Vous pouvez ensuite créer un index sur Zip seul qui serait utilisé dans ce cas.

Soit dit en passant, nous pouvons tirer parti du fait qu'avec l'indexation à plusieurs colonnes, la première colonne d'index est toujours utilisable pour la recherche et lorsque vous recherchez uniquement par «état», elle est efficace mais pas aussi efficace que l'index à colonne unique sur «l'état» "

Je suppose que la réponse que vous recherchez est que cela dépend de vos clauses where de vos requêtes fréquemment utilisées et également de vos regroupements.

L'article vous aidera beaucoup. :-)

evilhomer
la source
2
Alors, la meilleure chose à faire serait de définir un index pour l'état, le comté et le zip en plus d'un index individuel pour chaque colonne?
Maxim Zaslavsky
12
@jball Ai-je raté quelque chose ici? Il semble que l'article concerne principalement les différences entre les limitations de version de SQL Server. L'article aurait-il pu être déplacé?
Ian R. O'Brien
@Ian, il semble que quelque chose a été perdu dans les 3 ans à venir depuis que j'ai trié le lien d'origine depuis plus de 4 ans. Je peux vous dire que le billet de blog a le titre correct auquel a été lié par evilhomer, mais il semble que les blogs de suivi de la série ne soient plus faciles à trouver à partir de ce premier message. Vous devrez parcourir les archives du blog de Kimberly pour voir si vous pouvez retrouver les autres dans la série.
jball
1
1) "Fondamentalement [Index clusterisé avec la première colonne IDENTITY] aide votre insertion de données à la fin de l'index" est correcte. «et ne pas provoquer beaucoup d'E / S de disque et de fractionnements de page» est totalement faux dans un système multi-utilisateur. La vérité est qu'elle garantit une forte contention (faible concurrence) dans un système multi-utilisateur. 2) L'index cluster devrait être une clé relationnelle, c'est-à-dire. pas un IDENTITY, GUID, etc. 3) "Puis un index avec état, comté, zip. Sera utilisé dans ces trois recherches." est faux et contredit "la première colonne est utilisable". Les cols 2nd & subs de l'index ne sont pas utilisables pour la recherche.
PerformanceDBA
81

Oui. Je vous recommande de consulter les articles de Kimberly Tripp sur l'indexation .

Si un index est "couvrant", alors il n'est pas nécessaire d'utiliser autre chose que l'index. Dans SQL Server 2005, vous pouvez également ajouter des colonnes supplémentaires à l'index qui ne font pas partie de la clé, ce qui peut éliminer les déplacements vers le reste de la ligne.

Avoir plusieurs index, chacun sur une seule colonne peut signifier qu'un seul index est utilisé du tout - vous devrez vous référer au plan d'exécution pour voir quels effets offrent les différents schémas d'indexation.

Vous pouvez également utiliser l'assistant d'optimisation pour déterminer quels index permettraient à une requête ou à une charge de travail donnée de fonctionner de manière optimale.

Cade Roux
la source
7
Kimberly Tripp sait de quoi elle parle. J'étais en train de parler d'elle et elle connaît ce truc à l'envers. Très bon conseil.
evilhomer
@CadeRoux Si la plupart du temps ma clause where a 2 colonnes dans la relation '&', sera-t-il préférable d'avoir un index multi-colonnes sur eux ou un index sur les deux colonnes
C'est un piège du
2
@RachitGupta One index avec les deux colonnes
Cade Roux
40

L'index multi-colonnes peut être utilisé pour les requêtes référençant toutes les colonnes:

SELECT *
FROM TableName
WHERE Column1=1 AND Column2=2 AND Column3=3

Cela peut être recherché directement à l'aide de l'index multi-colonnes. D'un autre côté, au plus un des index à colonne unique peut être utilisé (il devrait rechercher tous les enregistrements ayant Colonne1 = 1, puis vérifier Colonne2 et Colonne3 dans chacun d'eux).

MobyDX
la source
24
C'est correct. Cependant, le fait d'avoir ces colonnes comme un seul index accélérerait encore considérablement les choses. Habituellement, l'une des valeurs dans les colonnes réduit tellement l'ensemble résultant qu'il n'est pas important de rechercher le reste sans index et l'optimiseur est bon pour choisir cette valeur.
TToni
16

Un élément qui semble avoir été oublié est la transformation des étoiles. Les opérateurs Index Intersection résolvent le prédicat en calculant l'ensemble de lignes frappées par chacun des prédicats avant d'effectuer des E / S sur la table de faits. Sur un schéma en étoile, vous indexeriez chaque clé de dimension individuelle et l'optimiseur de requête peut résoudre les lignes à sélectionner par le calcul d'intersection d'index. Les index sur les colonnes individuelles offrent la meilleure flexibilité pour cela.

ConcernedOfTunbridgeWells
la source
+1 pour la bonne explication liée de la façon dont les indices (ordinaires) sont utilisés, pertinents pour la question.
RobM
7

Si vous avez des requêtes qui utiliseront fréquemment un ensemble de colonnes relativement statiques, la création d'un index de couverture unique qui les inclut toutes améliorera considérablement les performances.

En plaçant plusieurs colonnes dans votre index, l'optimiseur n'aura à accéder directement à la table que si une colonne n'est pas dans l'index. Je les utilise beaucoup dans l'entreposage de données. L'inconvénient est que cela peut coûter cher, surtout si les données sont très volatiles.

La création d'index sur des colonnes uniques est utile pour les opérations de recherche fréquemment rencontrées dans les systèmes OLTP.

Vous devez vous demander pourquoi vous indexez les colonnes et comment elles seront utilisées. Exécutez des plans de requête et voyez quand ils sont accessibles. Le réglage d'index est autant d'instinct que la science.

Bob Probst
la source