En étudiant pour l'examen 70-433, j'ai remarqué que vous pouvez créer un indice de couverture de l'une des deux manières suivantes.
CREATE INDEX idx1 ON MyTable (Col1, Col2, Col3)
-- OU --
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
La clause INCLUDE est nouvelle pour moi. Pourquoi l'utiliseriez-vous et quelles directives suggéreriez-vous pour déterminer s'il faut créer un index de couverture avec ou sans la clause INCLUDE?
SELECT
et pour d'autres non? \Vous utiliseriez INCLUDE pour ajouter une ou plusieurs colonnes au niveau feuille d'un index non clusterisé, si ce faisant, vous pouvez "couvrir" vos requêtes.
Imaginez que vous devez rechercher l'ID d'un employé, l'ID du service et le nom de famille.
S'il vous arrive d'avoir un index non clusterisé sur (EmployeeID, DepartmentID), une fois que vous avez trouvé les employés pour un département donné, vous devez maintenant faire une "recherche de signet" pour obtenir le véritable enregistrement complet de l'employé, juste pour obtenir la colonne du nom de famille . Cela peut devenir assez cher en termes de performances, si vous trouvez beaucoup d'employés.
Si vous aviez inclus ce nom de famille dans votre index:
toutes les informations dont vous avez besoin sont alors disponibles au niveau feuille de l'index non clusterisé. Juste en cherchant dans l'index non clusterisé et en trouvant vos employés pour un département donné, vous avez toutes les informations nécessaires, et la recherche de signets pour chaque employé trouvé dans l'index n'est plus nécessaire -> vous gagnez beaucoup de temps.
De toute évidence, vous ne pouvez pas inclure chaque colonne dans chaque index non clusterisé - mais si vous avez des requêtes auxquelles il manque une ou deux colonnes à "couvrir" (et qui sont souvent utilisées), il peut être très utile d'INCLURE celles-ci. dans un index non cluster approprié.
la source
JOIN
de la requête, et lesINCLUDE
s doivent être les données que vous récupérez mais pas le tri.Cette discussion passe à côté du point important: la question n'est pas de savoir s'il est préférable d'inclure les "colonnes non clés" comme colonnes d' index ou comme colonnes incluses .
La question est de savoir combien il est coûteux d'utiliser le mécanisme d'inclusion pour inclure des colonnes qui ne sont pas vraiment nécessaires dans l'index ? (ne fait généralement pas partie des clauses where, mais est souvent inclus dans les sélections). Votre dilemme est donc toujours:
Où: id1, id2 ... idN sont des colonnes souvent utilisées dans les restrictions et col1, col2 ... colN sont des colonnes souvent sélectionnées, mais généralement pas utilisées dans les restrictions
(L'option d'inclure toutes ces colonnes dans le cadre de la clé d'index est juste toujours idiote (à moins qu'elles ne soient également utilisées dans des restrictions) - car il serait toujours plus coûteux à maintenir car l'index doit être mis à jour et trié même lorsque le "clés" n'ont pas changé).
Utilisez donc l'option 1 ou 2?
Réponse: Si votre table est rarement mise à jour - principalement insérée dans / supprimée de - alors il est relativement peu coûteux d'utiliser le mécanisme d'inclusion pour inclure certaines "colonnes chaudes" (qui sont souvent utilisées dans les sélections - mais pas souvent dans les restrictions) car les insertions / suppressions nécessitent de toute façon la mise à jour / tri de l'index et donc peu de surcharge supplémentaire est associée au stockage de quelques colonnes supplémentaires tout en mettant déjà à jour l'index. La surcharge correspond à la mémoire supplémentaire et au processeur utilisés pour stocker des informations redondantes sur l'index.
Si les colonnes que vous envisagez d'ajouter en tant que colonnes incluses sont souvent mises à jour (sans que la clé d' index -colonnes soit mise à jour) - ou - si elles sont si nombreuses que l'index se rapproche d'une copie de votre table - utilisez l'option 1 Je suggère! De plus, si l'ajout de certaines colonnes d'inclusion ne fait aucune différence dans les performances - vous voudrez peut-être ignorer l'idée de les ajouter :) Vérifiez qu'elles sont utiles!
Le nombre moyen de lignes pour les mêmes valeurs dans les clés (id1, id2 ... idN) peut également avoir une certaine importance.
Notez que si une colonne - qui est ajoutée en tant que colonne d'index incluse - est utilisée dans la restriction : tant que l'index en tant que tel peut être utilisé (en fonction de la restriction par rapport à la clé d' index -colonnes) - SQL Server correspond la restriction de colonne par rapport à l'index (leaf-node-values) au lieu de faire le tour coûteux de la table elle-même.
la source
Les colonnes d'index de base sont triées, mais les colonnes incluses ne sont pas triées. Cela économise des ressources dans la gestion de l'index, tout en permettant de fournir les données dans les colonnes incluses pour couvrir une requête. Ainsi, si vous souhaitez couvrir des requêtes, vous pouvez placer les critères de recherche pour localiser les lignes dans les colonnes triées de l'index, mais ensuite "inclure" des colonnes supplémentaires non triées avec des données non liées à la recherche. Cela aide certainement à réduire la quantité de tri et de fragmentation dans la maintenance des index.
la source
Les raisons pour lesquelles (y compris les données au niveau des feuilles de l'indice) ont été bien expliquées. La raison pour laquelle vous donnez deux secousses à ce sujet, c'est que lorsque vous exécutez votre requête, si vous n'avez pas les colonnes supplémentaires incluses (nouvelle fonctionnalité dans SQL 2005), SQL Server doit aller à l'index cluster pour obtenir les colonnes supplémentaires ce qui prend plus de temps et ajoute plus de charge au service SQL Server, aux disques et à la mémoire (le cache de tampon pour être spécifique) lorsque de nouvelles pages de données sont chargées en mémoire, ce qui peut potentiellement pousser d'autres données plus souvent nécessaires hors du cache de tampon.
la source
Une considération supplémentaire que je n'ai pas vue dans les réponses déjà données, est que les colonnes incluses peuvent être de types de données qui ne sont pas autorisés en tant que colonnes de clé d'index, telles que varchar (max).
Cela vous permet d'inclure de telles colonnes dans un index de couverture. J'ai récemment dû le faire pour fournir une requête générée par nHibernate, qui avait beaucoup de colonnes dans SELECT, avec un index utile.
la source
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:
Cet index est meilleur si votre requête ressemble à ceci:
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 lacol2
colonne dans la clé de l'index.Supposons que ce n'est pas le cas et que nous l'avons
col2
dans laINCLUDE
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:
Pour optimiser cette requête, l'index suivant serait parfait:
Si vous vérifiez déjà quels index vous avez sur cette table, votre index précédent pourrait toujours être là:
Maintenant , vous savez que
Col2
etCol3
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'ajouteranother_column
à la fin de la partie clé de l'index (aprèscol1
). Il y a peu de risques de casser quoi que ce soit: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 ajoutantanother_col
juste aprèsCol1
.Que se passe-t-il si vous ajoutez
another_col
entreCol1
etCol2
? 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:
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
la source
Il existe une limite à la taille totale de toutes les colonnes intégrées dans la définition d'index. Cela dit, je n'ai jamais eu à créer un index aussi large. Pour moi, le plus grand avantage est le fait que vous pouvez couvrir plus de requêtes avec un index qui a inclus des colonnes car elles n'ont pas besoin d'être définies dans un ordre particulier. Pensez à est comme un index dans l'index. Un exemple serait le StoreID (où StoreID est une faible sélectivité, ce qui signifie que chaque magasin est associé à un grand nombre de clients), puis les données démographiques des clients (LastName, FirstName, DOB): si vous insérez simplement ces colonnes dans cet ordre (StoreID, LastName , FirstName, DOB), vous ne pouvez rechercher efficacement que les clients pour lesquels vous connaissez StoreID et LastName.
D'un autre côté, définir l'index sur StoreID et inclure les colonnes LastName, FirstName, DOB vous permettrait essentiellement de faire deux prédicats de recherche d'index sur StoreID, puis de rechercher un prédicat sur n'importe laquelle des colonnes incluses. Cela vous permettrait de couvrir toutes les permutations de recherche possibles tant qu'il commence par StoreID.
la source