Une des raisons de préférer INCLUDE
les colonnes-clés si vous n'avez pas besoin de cette colonne dans la clé est la documentation. Cela rend l'évolution des index beaucoup plus facile à l'avenir.
Considérant votre exemple:
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
Cet index est meilleur si votre requête ressemble à ceci:
SELECT col2, col3
FROM MyTable
WHERE col1 = ...
Bien sûr, vous ne devez pas mettre de colonnes INCLUDE
si vous pouvez obtenir un avantage supplémentaire de les avoir dans la partie clé. Les deux requêtes suivantes préfèrent en fait la col2
colonne dans la clé de l'index.
SELECT col2, col3
FROM MyTable
WHERE col1 = ...
AND col2 = ...
SELECT TOP 1 col2, col3
FROM MyTable
WHERE col1 = ...
ORDER BY col2
Supposons que ce n'est pas le cas et que nous l'avons col2
dans la INCLUDE
clause car il n'y a tout simplement aucun avantage à l'avoir dans la partie arborescente de l'index.
Avance rapide de quelques années.
Vous devez régler cette requête:
SELECT TOP 1 col2
FROM MyTable
WHERE col1 = ...
ORDER BY another_col
Pour optimiser cette requête, l'index suivant serait parfait:
CREATE INDEX idx1 ON MyTable (Col1, another_col) INCLUDE (Col2)
Si vous vérifiez déjà quels index vous avez sur cette table, votre index précédent pourrait toujours être là:
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
Maintenant , vous savez que Col2
et Col3
ne faites pas partie de l'arbre d'index et ne sont donc pas utilisé pour réduire la plage d'index de lecture , ni pour commander les lignes. Il est plutôt sûr d'ajouter another_column
à la fin de la partie clé de l'index (après col1
). Il y a peu de risques de casser quoi que ce soit:
DROP INDEX idx1 ON MyTable;
CREATE INDEX idx1 ON MyTable (Col1, another_col) INCLUDE (Col2, Col3);
Cet indice deviendra plus grand, ce qui comporte encore certains risques, mais il est généralement préférable d'étendre les indices existants plutôt que d'en introduire de nouveaux.
Si vous aviez un index sans INCLUDE
, vous ne pourriez pas savoir quelles requêtes vous briseriez en ajoutant another_col
juste après Col1
.
CREATE INDEX idx1 ON MyTable (Col1, Col2, Col3)
Que se passe-t-il si vous ajoutez another_col
entre Col1
et Col2
? D'autres requêtes en souffriront-elles?
Il existe d'autres "avantages" par INCLUDE
rapport aux colonnes clés si vous ajoutez ces colonnes juste pour éviter de les extraire du tableau . Cependant, je considère l'aspect documentation comme le plus important.
Pour répondre à ta question:
Quelles lignes directrices suggéreriez-vous pour déterminer s'il faut créer un indice de couverture avec ou sans la clause INCLUDE?
Si vous ajoutez une colonne à l'index dans le seul but d'avoir cette colonne disponible dans l'index sans visiter la table, placez-la dans la INCLUDE
clause.
Si l'ajout de la colonne à la clé d'index apporte des avantages supplémentaires (par exemple pour order by
ou parce qu'elle peut réduire la plage d'index de lecture), ajoutez-la à la clé.
Vous pouvez lire une discussion plus longue à ce sujet ici:
https://use-the-index-luke.com/blog/2019-04/include-columns-in-btree-indexes