Couvrant des index lorsque des colonnes supplémentaires uniquement déterminées par index ordonné en clusters

StackOverflow https://stackoverflow.com/questions/1927399

Question

Si je dois mettre à jour MYTAB de luTab comme suit

update myTab
  set LookupVale = (select LookupValue from luTab B
                                       where B.idLookup = myTab.idLookup)

luTab est constitué de 2 colonnes (idLookup (unique), LookupValue)

Ce qui est préférable: un index ordonné en clusters unique sur idLookup, ou un sur idLookup et Lookupvalue combinés? Est-ce un indice de couverture va faire une différence dans cette situation?

(je suis surtout intéressé par serveur SQL)


Epilogue:

J'ai suivi des tests de Krips ci-dessous avec des rangées de 27M à MYTAB, 1.5M lignes luTab. La partie essentielle semble être le caractère unique de l'indice. Si l'indice est spécifié comme unique, la mise à jour utilise une table de hachage. Si elle n'est pas spécifié comme unique, puis la mise à jour par la première aggreates luTab idLookup (Stream Aggegate) et utilise ensuite une boucle imbriquée. Cela est beaucoup plus lent. Lorsque j'utilise l'index étendu, SQL est désormais plus assued que ce LookupValue est unique, sa force vers le bas le plus lent, route boucle agrégat imbriqué flux

Était-ce utile?

La solution

J'ai créé vos tables et chargé seulement quelques enregistrements (50 ou si recherche, et 15 MYTAB).

Alors j'ai essayé différentes options d'index. L'indice Seek sur luTab a toujours un coût de 29%.

Le bit est intéressant que si vous ajoutez dans la colonne LookupValue à l'indice sur luTab le plan d'exécution montre deux étapes supplémentaires après l'Index Seek: flux d'agrégats et Assertion. Bien que le coût est de 0%, qui peut aller avec plus de données.

J'ai aussi essayé un index non cluster uniquement sur idLookup, et notamment LookupValue comme une « colonne Inclus ». De cette façon, les pages de données ne doivent pas nécessairement être accessible pour récupérer que cette colonne. Cela peut être une option pour vous, bien que le plan d'exécution ne montre pas quelque chose de différent (mais ils n'ont pas soit Stream Aggregate / Assertion).

-Krip

Autres conseils

Tout d'abord:

  • Un indice de couverture est toujours non-cluster
  • Vous devriez toujours avoir un PK et un index ordonné en clusters (il y a même par défaut sur SQL Server)

Les 2 concepts sont distincts

  • Votre PK (cluster) serait idLookup si cela identifie de manière unique une ligne
  • L'indice de couverture serait (idLookup) Include (LookupValue)

Cependant:

  • idLookup est le PK (cluster), de sorte que vous n'avez pas besoin d'un index de couverture
  • l'index cluster (PK) est implicitement « couverture » par la nature d'un index ordonné en clusters (simplement, l'indice est données au niveau le plus bas)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top