Quelles sont les considérations de performances entre l'utilisation d'un PK large par rapport à une clé synthétique distincte et à l'UQ?


10

J'ai plusieurs tableaux où les enregistrements peuvent être identifiés de manière unique avec plusieurs grands domaines d'activité. Dans le passé, j'ai utilisé ces champs en tant que PK, avec ces avantages à l'esprit:

  • Simplicité; il n'y a pas de champs superflus et juste un index
  • Le clustering permet des jointures de fusion rapides et des filtres basés sur des plages

Cependant, j'ai entendu des arguments en faveur de la création d'un IDENTITY INTPK synthétique et de l'application de la clé métier avec une UNIQUEcontrainte distincte . L'avantage est que le PK étroit fait des indices secondaires beaucoup plus petits.

Si un tableau n'a pas d'indices autres que le PK, je ne vois aucune raison de favoriser la deuxième approche, bien que dans un grand tableau, il soit probablement préférable de supposer que des indices pourraient être nécessaires à l'avenir, et donc de favoriser le PK synthétique étroit . Suis-je en manque de considérations?

Soit dit en passant, je ne m'oppose pas à l'utilisation de clés synthétiques dans les entrepôts de données, je souhaite simplement savoir quand utiliser un seul PK large et quand utiliser un PK étroit plus un Royaume-Uni large.


1
vous pouvez trouver ceci ou cela utile parmi d'autres questions sur le site
Jack dit essayer topanswers.xyz

Réponses:


11

Il n'y a pas d'inconvénient significatif à utiliser la clé naturelle comme index clusterisé

  • il n'y a pas d'index non clusterisé
  • pas de clés étrangères référençant cette table (c'est une ligne parent)

L'inconvénient serait une augmentation des fractionnements de pages, car les insertions de données seraient distribuées dans toutes les données, plutôt qu'à la fin.

Lorsque vous avez des index FK ou NC, l'utilisation d'un index cluster étroit, numérique et croissant présente des avantages. Vous ne répétez que quelques octets de données par entrée NC ou FK, pas la clé business / natural while.

Pour savoir pourquoi, lisez également les 5 articles de Google

Notez que j'ai évité l'utilisation de "clé primaire".

Vous pouvez avoir l'index cluster sur la clé de substitution, mais conserver le PK sur les règles métier, mais en tant que non cluster. Assurez-vous simplement que le cluster est unique car SQL ajoutera un "uniquifier" pour le faire.

Enfin, il peut être judicieux d'avoir une clé de substitution mais pas à l'aveuglette sur chaque table : les tables plusieurs-plusieurs n'en ont pas besoin, ou là où une clé composée des tables parentes suffira.


+1 pour la référence Mme Tripp excellents articles en indexation.
Fabricio Araujo

2
+1 pour le point que les performances n'ont rien à voir avec les clés primaires et tout à voir avec les index.
nvogel

4

Bien que je risque d'indiquer l'évidence, un index sur une clé de substitution (un numéro d'identification) est utile si vous devez localiser les choses par leur numéro d'identification. Les utilisateurs ne vont pas traiter le numéro d'identification; ils vont traiter avec du texte lisible par l'homme. Vous devez donc beaucoup faire circuler le texte et son numéro d'identification, de sorte que l'interface utilisateur puisse afficher le texte et fonctionner sur le numéro d'identification.

Les dbms utiliseront ce type d'index pour prendre en charge les clés étrangères, si vous les définissez de cette façon.

Vous pouvez parfois améliorer les performances en utilisant des numéros d'identification comme clés étrangères, mais ce n'est pas une amélioration absolue. Sur notre système OLTP, les clés étrangères utilisant des clés naturelles ont surpassé les clés étrangères utilisant des numéros d'identification sur une suite de tests d'environ 130 (je pense) requêtes représentatives. (Parce que les informations importantes sont souvent portées dans les clés, l'utilisation des clés naturelles a évité beaucoup de jointures.) L'accélération médiane était un facteur de 85 (les jointures utilisant des numéros d'identification ont pris 85 fois plus de temps pour renvoyer des lignes).

Les tests ont montré que les jointures sur les numéros d'identification ne seraient pas plus rapides que les lectures sur les clés naturelles dans notre base de données jusqu'à ce que certaines tables atteignent plusieurs millions de lignes. La largeur de la ligne a beaucoup à voir avec cela - des lignes plus larges signifient que moins de lignes tiennent sur une page, vous devez donc lire plus de pages pour obtenir des «n» lignes. Presque toutes nos tables sont en 5NF; la plupart des tableaux sont assez étroits.

Au moment où les jointures commencent à effectuer des lectures simples ici , le fait de placer des tables et des index critiques sur un disque SSD peut niveler les performances dans les centaines de millions de lignes.


3

J'ai une base de données oltp entière conçue en utilisant des colonnes d'identité pour le clustering + pk. Cela fonctionne assez rapidement sur l'insertion / recherche mais j'ai vu quelques problèmes:
1. l'option de remplissage d'index est inutile car les insertions ne se produisent qu'à la fin de l'index
2. plus d'espace de stockage. J'ai des tables avec des dizaines de millions d'enregistrements et 1 int prend de l'espace par lui-même. Chaque table avec une colonne d'identité pour son pk doit avoir un autre index pour les recherches commerciales, donc encore plus de stockage requis.
3. évolutivité. C'est le pire problème. Parce que chaque insert va à la fin de l'index, chaque insert ne mettra l'accent que sur la fin de l'index (allocation, io pour les écritures, etc.). En utilisant une clé métier comme clé de clustering, vous pouvez distribuer les insertions de manière uniforme sur l'index. Cela signifie que vous venez d'éliminer un gros hotspot. Vous pouvez facilement utiliser plus de fichiers pour un index, chaque fichier sur un lecteur distinct, chaque lecteur fonctionnant séparément.

J'ai commencé à changer mes tables d'une colonne d'identité en clés naturelles (peut-être séparées pour le clustering et pk). Ça va mieux maintenant.

Je suggérerais ce qui suit (au moins pour une base de données oltp):
1. utiliser comme clé de clustering les bonnes colonnes dans le bon ordre afin d'optimiser les requêtes les plus fréquentes
2. utiliser un pk les bonnes colonnes qui ont du sens pour votre table

Si la clé en cluster n'est pas simple et contient des caractères (char [], varchar, nvarchar), je pense que la réponse est «cela dépend», vous devez analyser individuellement chaque cas.

Je garde le principe suivant: optimiser pour la requête la plus courante tout en minimisant le pire des cas.

J'ai presque oublié un exemple. J'ai quelques tableaux qui se référencent. Si cette table a une colonne d'identité pour sa clé primaire, l'insertion d'une ligne peut nécessiter une mise à jour et l'insertion de plusieurs lignes à la fois peut être difficile, voire impossible (cela dépend de la conception de la table).


4
Votre concept de "hotspot" est un mythe: dba.stackexchange.com/questions/1584/… Et quand vous dites "ça se sent mieux maintenant". avez-vous évalué?
gbn

4
Oui, les écritures sont effectuées en mémoire et non directement sur le disque. Si vous écrivez 20 nouvelles lignes sur une page, il n'y a qu'une seule écriture physique dans le fichier de données lorsque le point de contrôle se produit.
mrdenny

@mrdenny avec suffisamment d'insertions écrivant tout à la fin de l'index enverrait toutes les requêtes d'écriture io dans le même fichier. Je soupçonne qu'en utilisant des transactions OLTP normales, ce scénario sera difficile à reproduire, mais en utilisant certains scénarios spéciaux comme l'insertion en bloc / par lots d'enregistrements, l'utilisation de ssis pour déplacer des données d'entreprise vous y mènera.
Catalin Adler

1
@ user973156 oui toutes les requêtes feraient pour le même fichier, mais les écritures ne vont pas réellement sur le disque jusqu'au point de contrôle qui ne se produit que toutes les minutes (par défaut) ou lorsque le tampon d'écriture est plein à 50%. Peu importe comment vous écrivez les données, cette règle s'applique toujours.
2011

2
@ user973156 L'utilisation d'une clé de clustering distribuée de manière aléatoire provoquera la fragmentation de l'index. La fragmentation de l'index entraînera des problèmes de performances. Et votre table deviendra suffisamment grande pour que la défragmentation d'index prenne "longtemps" et consomme de l'espace de journal et potentiellement de l'espace tempDB. Quand j'ai des gens comme Kimberly Tripp qui me disent que c'est une bonne idée, j'écoute. ( sqlskills.com/BLOGS/KIMBERLY/post/… )
Matt M

2

Du point de vue des performances, le choix de la clé qui est la clé "primaire" ne fait aucune différence. Il n'y a aucune différence entre l'utilisation d'une PRIMARY KEY et une contrainte UNIQUE pour appliquer vos clés.

Les performances sont déterminées par la sélection et le type d'index et d'autres options de stockage et par la façon dont les clés sont utilisées dans les requêtes et le code.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.