Pourquoi les vues indexées n'autorisent-elles pas les index cluster non uniques?

12

J'ai cherché à utiliser les vues indexées pour augmenter les performances de certaines de nos vues les plus couramment utilisées.

Cependant, les vues indexées ne prennent pas en charge les index cluster non uniques, ce qui va un peu à l'encontre de la priorité définie par le reste de la structure de la base de données.

Par exemple, voici une version simplifiée de quelques-uns de nos tableaux.

-Groups-
Group ID    GroupName

-Users-
UserKey    UserName    FullName     GroupID

Les index se trouvent sur Groups.GroupID (non cluster) et Users.GroupID (cluster). La clé en cluster se trouvant sur GroupID dans la table Users, car le plus souvent une plage d'utilisateurs d'un groupe spécifique serait récupérée. De toute évidence, vous auriez plusieurs utilisateurs par groupe, donc cet index cluster n'est pas unique.

Cela me laisse un peu incertain sur la façon de suivre cette priorité lors de l'indexation de mes vues telles que cet exemple, car je ne peux pas avoir un index cluster non unique.

ConsumableID    ConsumableVariantID AllowThresholdOverwrite FullPath    GroupID ManufacturerID  Type    ModelID
101              29                 1                       0.1.2.4.    4       3               3       2

En réalité, la seule valeur de cette vue qui serait toujours unique est la colonne ConsumableID, donc je n'ai que peu de choix quant à l'endroit où placer mon index.

Pourquoi les vues n'autorisent-elles pas les index cluster non uniques lorsque les tables normales le font?

Amical
la source
3
Il y a une très brève explication au bas de cette page intitulée "Pourquoi le premier index d'une vue doit-il être CLUSTERE et UNIQUE?" mais cela ne fait pas beaucoup de détails. Je serais certainement intéressé à entendre une explication plus détaillée.
Steve Pettifer
5
Quelques commentaires: 1 - Il n'y a aucune raison pour laquelle vous ne pouvez pas vous regrouper (GroupID, UserID). Ne vous limitez pas à une seule colonne pour la clé. 2 - J'imagine que la limitation d'une vue est due au fait qu'il s'agit d'un objet de données supplémentaire qui doit avoir des lignes facilement liées aux index NC. Pour une table, la clé CI non unique est accompagnée d'un int, mais je pense que ce serait plus difficile avec une vue indexée car ce n'est pas une table réelle mais doit REFLÉTER une table réelle.
JNK

Réponses:

22

L'explication suivante est donnée dans cet article technique de Microsoft :

Pourquoi le premier index d'une vue doit-il être CLUSTER et UNIQUE?

Il doit être UNIQUE pour permettre une recherche facile des enregistrements dans la vue par valeur clé lors de la maintenance de la vue indexée et pour empêcher la création de vues avec des doublons, ce qui nécessiterait une logique particulière pour la maintenance. Il doit être mis en cluster car seul un index clusterisé peut appliquer l'unicité et stocker les lignes en même temps.

SQL Server utilise un système d'algèbre delta pour garder les vues indexées en phase avec les données de base. Il intègre également automatiquement des opérateurs de plan de requête de maintenance des vues pour chaque requête DML qui affecte une ou plusieurs vues indexées. Le fait d'avoir un index cluster unique sur la vue simplifie considérablement les détails d'implémentation.

L'agencement actuel permet d'incorporer des formes d'arbre d'opérateur de maintenance à forme fixe dans l'arbre de requête DML de base, fournissant une orthogonalité qui simplifie également les tests. En fin de compte, les vues indexées pourraient être améliorées un jour pour prendre en charge les index cluster non uniques, mais là encore, tout est possible compte tenu du temps illimité et des ressources illimitées (aucune des deux ne s'applique à l'équipe de développement SQL Server au moment de la rédaction).

Pour un exemple montrant à quel point la création d'un plan de requête de mise à jour peut être complexe et avec quelle facilité des bogues subtils peuvent se glisser, consultez cet exemple de bogue qui se produit avec MERGEles index filtrés (une fonctionnalité qui a une connexion étroite avec les vues indexées).

Paul White 9
la source
2
Un bogue similaire peut se produire si vous essayez de mettre à jour une vue indexée qui a une GROUP BYclause mais toutes les expressions de regroupement ne sont pas des clés dans l'index cluster. Il est valide à partir de SQL Server 2014.
Quassnoi
4

Dans SQL Server, toutes les clés d'index doivent être uniques en interne. Cela est nécessaire pour obtenir des clés de verrouillage qui adressent exactement une ligne. Il est également requis pour la maintenance de l'index. Imaginez un NCI sur une colonne qui n'a qu'une seule valeur (100% en double). Si une ligne est supprimée de la table, le moteur de stockage doit trouver la ligne NCI correspondante et la supprimer également. Si toutes les lignes NCI sont indiscernables, cela serait impossible.

Vous voyez donc que le CI d'une vue doit être (en interne) unique pour que le moteur fonctionne.

Si vous ne rendez pas un index unique, SQL Server le rend toujours unique en interne. Dans le cas d'un NCI sur une table de tas, il ajoute le signet de ligne. Dans le cas d'un CI non unique, il ajoute une colonne uniquifier. Dans le cas d'un NCI sur une table avec un CI, il ajoute toutes les colonnes de clés de CI que vous n'avez pas déjà spécifiées (cela peut inclure l'unificateur).

Aucune colonne évidente ne peut être ajoutée en cas de vue indexée. SQL Server ne peut donc pas le faire automatiquement.

Normalement, il est assez évident pour un humain quelles colonnes vous pouvez ajouter pour que la vue ait un ensemble unique de colonnes à utiliser dans le CI. Ce sont normalement les colonnes PK ou CI de l'une des tables sous-jacentes. Si la vue a un GROUP BYindex normal sur les clés de regroupement.

usr
la source
2
Je suggère fortement de réviser la formulation de cette réponse. Bien qu'il contienne un point valide concernant la question d'origine, il peut sembler qu'il suggère que tous les index non uniques contiennent des uniquificateurs, ce qui n'est pas le cas.
spaghettidba
@spaghettidba merci, je ne l'ai pas remarqué. J'espère que c'est mieux maintenant.
usr
Désolé pas encore. Vous mélangez deux choses ensemble. Les index non clusterisés ne doivent pas nécessairement être uniques et ne sont pas uniques en interne: vous n'insistez pas assez clairement sur ce point. Tout ce que vous dites dans votre réponse s'applique uniquement aux index clusterisés.
spaghettidba
@spaghettidba Les NCI sont toujours uniques en interne. Ils peuvent toujours sortir toutes les clés CI dans le cadre d'un plan de requête. Voir pastebin.com/vkGHpCsR La page de données NCI contient les deux colonnes.
usr
Je vois d'où tu viens. Plusieurs feuilles peuvent partager la même clé d'index, mais la clé de clustering est toujours incluse dans les NCI. Suffit-il de dire qu'ils sont toujours uniques en interne? Je ne pense pas.
spaghettidba