La question n'est pas de savoir quand le PK doit être un NC, mais plutôt de demander quelle est la clé appropriée pour l'index clusterisé.
Et la réponse dépend vraiment de la manière dont vous interrogez les données . L'index clusterisé a un avantage sur tous les autres index: puisqu'il inclut toujours toutes les colonnes, il couvre toujours. Par conséquent, les requêtes pouvant exploiter l'index clusterisé n'ont certainement pas besoin d'utiliser des recherches pour satisfaire certaines des colonnes et / ou prédicats projetés.
Une autre pièce du puzzle consiste à savoir comment utiliser un index . Il existe trois modèles typiques:
- sondes, lorsqu'une seule valeur de clé est recherchée dans l'index
- analyses de plage, lorsqu'une plage de valeurs de clé est récupérée
- ordre par exigence, quand un index peut satisfaire un ordre sans nécessiter un tri aller-retour
Par conséquent, si vous analysez votre charge attendue (les requêtes) et découvrez qu'un grand nombre de requêtes utiliseraient un index particulier parce qu'elles utilisent un certain modèle d'accès bénéficiant d'un index, il est logique de proposer cet index en tant qu'index clusterisé.
Un autre facteur réside dans le fait que la clé d'index cluster est la clé de recherche utilisée par tous les index non cluster. Par conséquent, une clé d'index cluster étendue crée un effet d'entraînement et élargit tous les index non clusterisés. , plus de mémoire, moins de bonté.
Un bon index clusterisé est stable , il ne change pas pendant la durée de vie de l'entité, car une modification des valeurs de la clé d'index cluster signifie que la ligne doit être supprimée et réinsérée.
Et un bon index clusterisé grandit dans un ordre non aléatoire (chaque valeur de clé nouvellement insérée est plus grande que la valeur précédente) afin d'éviter les fractionnements de page et la fragmentation (sans déconner avec FILLFACTOR
s).
Alors, maintenant que nous savons ce qu'est une bonne clé d'index cluster, la clé primaire (qui est une propriété logique de modélisation de données) correspond-elle aux exigences? Si oui, alors la PK devrait être groupée. Si non, alors la PK ne devrait pas être en cluster.
Pour donner un exemple, considérons un tableau de données de vente. Chaque entrée a un identifiant qui est la clé primaire. Mais la grande majorité des requêtes demandent des données entre une date et une autre date. Par conséquent, la meilleure clé d'indexation en cluster serait la date de vente et non l' ID . Un autre exemple d’index clusterisé différent de la clé primaire est une clé de sélectivité très faible, telle qu’une «catégorie» ou un «état», une clé avec très peu de valeurs distinctes. Avoir une clé d'index cluster avec cette clé de sélectivité faible comme clé la plus à gauche, par exemple (state, id)
, a souvent du sens en raison des balayages de plages qui recherchent toutes les entrées dans un «état» particulier.
Une dernière remarque sur la possibilité d’une clé primaire non clusterisée sur un segment de mémoire (c’est-à-dire qu’il n’existe aucun index clusterisé). Il peut s'agir d'un scénario valide. La raison typique est que les performances des insertions en bloc sont essentielles, car les tas ont un débit de insertion en bloc nettement supérieur à celui des index clusterisés.
(state, id)
. Dans cet exemple, l'exigence "le bon index clusterisé croît de manière non aléatoire" ne sera pas satisfaite, n'est-ce pas? Alors peut-on le considérer comme un bon index clusterisé?La raison fondamentale pour utiliser les index clusterisés est indiquée sur Wikipedia :
Dites que j'ai une table de personnes et que ces personnes ont une colonne Pays et une clé primaire unique. C'est un tableau démographique, alors ce sont les seules choses qui me tiennent à cœur. quel pays et combien de personnes uniques sont liées à ce pays.
Je ne suis donc susceptible de ne jamais sélectionner que où ou ordre par la colonne pays; un index en cluster sur la clé primaire ne me fait aucun bien, je n'accède pas à ces données par PK, je les accède par cette autre colonne. Étant donné que je ne peux avoir qu'un seul index clusterisé sur une table, déclarer ma PK en tant que cluster m'empêcherait d'utiliser un index clusterisé sur un pays.
En outre, voici un bon article sur les index clusterisés et non clusterisés : il s'avère que les index clusterisés causaient des problèmes de performances d'insertion dans SQL Server 6.5 (ce qui, espérons-le, n'est pas pertinent pour la plupart d'entre nous ici).
Notez que ce n'est pas le cas dans les versions ultérieures.
la source
Si votre clé primaire est du
UNIQUEIDENTIFIER
, assurez-vous de spécifier que c'estNONCLUSTERED
. Si vous le faites en cluster, chaque insertion devra faire un tas de remaniement d'enregistrements pour insérer la nouvelle ligne à la position correcte. Ce sera la performance du réservoir.la source
UNIQUEIDENTIFIER
type séquentiel existe également et a la même probabilité de générer des clés uniques, bien qu'il souffre toujours d'une taille de 128.Un exemple très courant:
Customer
table avecCustomerID
commeCLUSTERED PRIMARY KEY
OrderID (PK), CustomerID, OrderDate
et quelques autres colonnesOrderPositions
avecOrderPositionID (PK), OrderId, ProductID, Amount, Price ...
Bien sûr, "ça dépend" est - comme presque toujours - la bonne réponse, mais la plupart des applications (pas BI-Reports) fonctionneront selon le client (par exemple, vous vous connectez en tant que client 278 sur le site Web et cliquez sur "Mes commandes" ou le commis liste toutes les commandes du client 4569 ou votre routine de facturation récapitulera toutes les commandes du client 137).
Dans ce cas, il n’aurait pas beaucoup de sens de regrouper la table en fonction du format
OrderID
. Oui, vous aurez des questionsSELECT ... WHERE OrderId = ?
concernant la liste des détails de la commande, mais il s’agit généralement d’une recherche courte et peu coûteuse (3 lectures).D'un autre côté, si vous souhaitez classer votre
Order
table en clusterCustomerID
, il ne serait pas nécessaire d'effectuer plusieurs recherches de clé à chaque fois que vous interrogez la tableCustomerId = ?
.Le
CLUSTERED INDEX
doit toujours êtreUNIQUE
, sinon SQL Server ajouterait invisible (= inutilisable) colonne INTUNIQUIFIER
pour assurer la uniquiness - et il serait beaucoup plus logique d'ajouter des données réelles (utilisables) puis des choses au hasard ( en fonction de l'ordre d'insertion).Parce qu'un client passera (espérons-le) plus d'une commande, nous devrons ajouter soit le
OrderID
ou (si vous triez habituellement pour cela) leOrderDate
(s'il s'agit d'une date / heure - sinon le client serait limité à une commande par jour) à leCLUSTERED INDEX
et se retrouver avec:CREATE UNIQUE CLUSTERED INDEX IX_Orders_UQ on Orders (CustomerID, OrderID)
Les mêmes règles s'appliquent à la
OrderPositions
table. Habituellement , la plupart des requêtes listera toutes les positions pour le ordre spécifique, vous devez donc créer le PK avec l'OrderPositionID
enNONCLUSTERED
etUNIQUE CLUSTERED INDEX
surOrderId, OrderPositionID
.BTW: il est correct que la
Customer
table soit groupée par son PK (leCustomerID
, parce que c'est une "table de premier niveau") et sera, dans une application typique, principalement interrogée par son code client.Les tables de recherche pures, par exemple
Genders
ou,InvoiceTypes
ouPaymentType
sont un autre exemple de table qui devrait être mise en cluster par sa PK (parce que vous les joindrez habituellement surGenderId
,InvoiceTypeId
ouPaymentTypeId
).la source
Lorsqu'un index en cluster est jugé plus bénéfique pour l'ensemble du système qu'un PK en cluster en utilisant une mesure de performance. Il ne peut y avoir qu'un seul index clusterisé sur une table.
Les exemples de mesures de performances sont le temps d'interrogation simple (vitesse), l'intégration des temps d'interrogation totaux par rapport à la table (efficacité) et l'obligation d'ajouter de nombreuses colonnes include à un très grand index non clusterisé afin d'obtenir des performances similaires à celles d'un cluster (taille). ).
Cela peut se produire lorsque les données sont généralement extraites à l'aide d'un index non unique, contenant des valeurs NULL (non autorisées dans une clé PK) ou si la clé PK a été ajoutée pour une raison secondaire (telle que la réplication ou l'identification des enregistrements de suivi d'audit).
la source