Je lisais Clustered
et Non Clustered Indexes
.
Clustered Index
- Il contient des pages de données. Cela signifie que les informations de ligne complètes seront présentes dans la colonne d'index clusterisé.
Non Clustered Index
- Il contient uniquement les informations du localisateur de lignes sous la forme d'une colonne d'index clusterisé (si disponible) ou de l'identificateur de fichier + numéro de page + nombre total de lignes dans une page. Cela signifie que le moteur de requête doit effectuer une étape supplémentaire afin de localiser les données réelles.
Requête - Comment puis-je vérifier la différence de performances à l'aide d'un exemple pratique car nous savons que la table ne peut en avoir qu'un Clustered Index
et fournit sorting
au Clustered Index Column
et Non Clustered Index
ne fournit pas sorting
et peut prendre Non Clustered Indexes
en charge 999 in SQL Server 2008
et 249 in SQL Server 2005
.
Réponses:
Très bonne question car c'est un concept si important. C'est un gros sujet cependant et ce que je vais vous montrer est une simplification afin que vous puissiez comprendre les concepts de base.
Premièrement, lorsque vous voyez une table de réflexion d' index clusterisé . Dans SQL Server, si une table ne contient pas d'index cluster, il s'agit d'un segment. La création d'un index cluster sur la table transforme en fait la table en une structure de type b-tree. Votre index cluster EST votre table il n'est pas séparé de la table
Vous êtes-vous déjà demandé pourquoi vous ne pouvez avoir qu'un seul index cluster? Eh bien, si nous avions deux index clusterisés, nous aurions besoin de deux copies de la table. Il contient les données après tout.
Je vais essayer d'expliquer cela en utilisant un exemple simple.
REMARQUE: J'ai créé le tableau dans cet exemple et l'ai rempli avec plus de 3 millions d'entrées aléatoires. Ensuite, a exécuté les requêtes réelles et collé les plans d'exécution ici.
Ce que vous devez vraiment comprendre, c'est la notation O ou l' efficacité opérationnelle . Supposons que vous ayez le tableau suivant.
Nous avons donc ici une table de base avec une clé en cluster sur CustomerID (la clé primaire est en cluster par défaut). Ainsi, la table est organisée / ordonnée en fonction de la clé primaire CustomerID. Les niveaux intermédiaires contiendront les valeurs CustomerID. Les pages de données contiendront la ligne entière, c'est donc la ligne du tableau.
Nous allons également créer un index non clusterisé sur le champ CustomerName. Le code suivant le fera.
Ainsi, dans cet index, vous trouverez sur les pages de données / nœuds de niveau feuille un pointeur vers les niveaux intermédiaires de l'index clusterisé. L'index est organisé / ordonné autour du champ CustomerName. Ainsi, le niveau intermédiaire contient les valeurs CustomerName et le niveau feuille contiendra le pointeur (ces valeurs de pointeur sont en fait les valeurs de clé primaire ou la colonne CustomerID).
Exactement si nous exécutons la requête suivante:
SQL lira probablement l'index clusterisé via une opération de recherche. Une opération de recherche est une recherche binaire qui est beaucoup plus efficace qu'une analyse qui est une recherche séquentielle. Ainsi, dans notre exemple ci-dessus, l'index est lu et en utilisant une recherche binaire, SQL peut éliminer les données qui ne correspondent pas aux critères que nous recherchons. Voir la capture d'écran ci-jointe pour le plan de requête.
Ainsi, le nombre d'opérations ou de notation O pour l'opération de recherche est le suivant:
Il s'agit donc de deux opérations. Cependant, si nous avons exécuté la requête suivante:
SQL va maintenant utiliser l'index non clusterisé sur le CustomerName pour effectuer la recherche. Cependant, puisqu'il s'agit d'un index non clusterisé, il ne contient pas toutes les données de la ligne.
Ainsi, SQL effectuera la recherche aux niveaux intermédiaires pour trouver les enregistrements qui correspondent, puis effectuera une recherche en utilisant les valeurs renvoyées pour effectuer une autre recherche sur l'index cluster (alias la table) pour récupérer les données réelles. Cela semble déroutant, je sais, mais lisez la suite et tout deviendra clair.
Étant donné que notre index non clusterisé ne contient que le champ CustomerName (les valeurs de champ indexées stockées dans les nœuds intermédiaires) et le pointeur vers les données qui sont le CustomerID, l'index n'a pas d'enregistrement de CustomerSurname. Le CustomerSurname doit être récupéré à partir de l'index ou de la table en cluster.
Lors de l'exécution de cette requête, j'obtiens le plan d'exécution suivant:
Il y a deux choses importantes à noter dans la capture d'écran ci-dessus
Pourquoi SQL suggère-t-il à nouveau l'index sur CustomerName? Eh bien, puisque l'index contient uniquement le CustomerID et le CustomerName SQL doit toujours trouver le CustomerSurname à partir des index de table / cluster.
Si nous avons créé l'index et que nous avons inclus la colonne CustomerSurname dans l'index, SQL pourrait satisfaire l'intégralité de la requête en lisant simplement l'index non cluster. C'est pourquoi SQL suggère que je modifie mon index non clusterisé.
Ici, vous pouvez voir l'opération supplémentaire que SQL doit faire pour obtenir la colonne CustomerSurname à partir de la clé en cluster
Ainsi, le nombre d'opérations est le suivant:
Il s'agit de 4 opérations pour extraire les valeurs. Deux fois le nombre d'opérations nécessaires par rapport à la lecture de l'index clusterisé. Ils vous montrent que votre index cluster est votre index le plus puissant car il contient toutes les données.
Juste pour clarifier un dernier point. Pourquoi dois-je dire que le pointeur dans l'index non cluster est la valeur de clé primaire? Eh bien pour démontrer que les nœuds de niveau feuille de l'index non clusterisé contiennent la valeur de clé primaire, je change ma requête en:
Dans cette requête, SQL peut lire le CustomerID à partir de l'index non cluster. Il n'a pas besoin d'effectuer une recherche sur l'index clusterisé. Vous pouvez le voir sur le plan d'exécution qui ressemble à ceci.
Notez la différence entre cette requête et la requête précédente. Il n'y a pas de recherche. SQL peut trouver toutes les données dans l'index non clusterisé
J'espère que vous pourrez commencer à comprendre que l'index cluster est la table et que les index non cluster NE contiennent PAS toutes les données. L'indexation accélérera les sélections car les recherches binaires peuvent être effectuées mais seuls les index clusterisés contiennent toutes les données. Ainsi, une recherche sur un index non clusterisé entraînera presque toujours le chargement de valeurs à partir de l'index clusterisé. Ces opérations supplémentaires rendent les index non cluster moins efficaces qu'un index cluster.
Espérons que cela arrange les choses. Si quelque chose n'a pas de sens, veuillez poster un commentaire et je vais essayer de clarifier. Il est assez tard ici et mon cerveau se sent un peu plat. Il est temps pour un taureau rouge.
la source
"Cela signifie que le moteur de requête doit effectuer une étape supplémentaire afin de localiser les données réelles."
Pas nécessairement - si l'index couvre une requête donnée, aucun déplacement ne doit être effectué vers les pages de données. De plus, avec les colonnes incluses, des colonnes supplémentaires peuvent être ajoutées à un index non clusterisé pour le rendre couvrant sans modifier la taille de la clé.
Donc, la réponse ultime est - cela dépend (sur beaucoup plus d'informations que vous ne pouvez vraiment couvrir dans une seule question) - vous devez comprendre toutes les capacités des index et le plan d'exécution pour une requête donnée peut différer de vos attentes.
Une règle générale que j'ai est qu'une table a toujours un index cluster (et généralement sur une identité ou un GUID séquentiel), mais des index non cluster sont ajoutés pour la performance. Mais il y a toujours des exceptions - les tables de tas ont une place, les index cluster plus larges ont une place. Les index apparemment redondants qui sont plus étroits pour contenir plus de lignes par page ont une place. etc.
Et je ne m'inquiéterais pas des limites des différents indices autorisés - cela ne va certainement pas entrer en jeu dans de nombreux exemples réels.
la source
there are always exceptions
- trop de gens omettent cela et pensent que chaque index cluster devrait êtreint identity
n'importe quoi.