web-dev-qa-db-fra.com

Les index clusterisés doivent-ils être uniques?

Que se passe-t-il si un index cluster n'est pas unique? Peut-il conduire à de mauvaises performances parce que les lignes insérées se dirigent vers une page de "débordement" de certaines sortes?

Est-il "rendu" unique et si oui, comment? Quelle est la meilleure façon de la rendre unique?

Je demande parce que j'utilise actuellement un index clusterisé pour diviser ma table en parties logiques, mais les performances sont moyennes, et récemment j'ai eu le conseil pour rendre mes index clusterisés uniques. J'aimerais avoir un deuxième avis là-dessus.

Merci!

75
thomaspaulb

Ils ne ont pour être uniques mais c'est certainement encouragé.
Je n'ai pas encore rencontré de scénario où je voulais créer un CI sur une colonne non unique.

Que se passe-t-il si vous créez un CI sur une colonne non unique

Si l'index cluster n'est pas un index unique, SQL Server rend toutes les clés en double uniques en ajoutant une valeur générée en interne appelée un uniqueifier

Est-ce que cela conduit à de mauvaises performances?

Ajouter un uniqueifier ajoute certainement des frais généraux dans le calcul et le stockage.
Si ces frais généraux seront perceptibles, cela dépend de plusieurs facteurs.

  • Combien de données la table contient.
  • Quel est le taux d'insertions.
  • À quelle fréquence l'IC est-il utilisé dans une sélection (lorsqu'il n'existe aucun index de couverture, presque toujours).

Modifier
comme l'a souligné Remus dans ses commentaires, il existe des cas d'utilisation où la création d'un CI non unique serait un choix raisonnable. Le fait de ne pas avoir rencontré l'un de ces scénarios montre simplement mon propre manque d'exposition ou de compétence (choisissez votre choix).

78

J'aime vérifier ce que la reine de l'indexation, Kimberly Tripp, a à dire sur le sujet:

Je vais commencer par ma recommandation pour la Clustering Key - pour deux raisons. Premièrement, c'est une décision facile à prendre et deuxièmement, prendre cette décision tôt permet d'éviter de manière proactive certains types de fragmentation. Si vous pouvez empêcher certains types de fragmentation de la table de base, vous pouvez minimiser certaines activités de maintenance (dont certaines, dans SQL Server 2000 ET moins dans SQL Server 2005), nécessitent que votre table soit hors ligne. OK, je reviendrai sur les trucs de reconstruction plus tard .....

Commençons par les éléments clés que je recherche dans une clé de clustering:

* Unique
* Narrow
* Static

Pourquoi Unique? Une clé de clustering doit être unique car une clé de clustering (lorsqu'elle existe) est utilisé comme clé de recherche de tous les index non clusterisés. Prenez par exemple un index à l'arrière d'un livre - si vous avez besoin de trouver les données vers lesquelles pointe une entrée d'index - cette entrée (l'entrée d'index) doit être unique sinon, quelle entrée d'index serait celle que vous recherchez ? Ainsi, lorsque vous créez l'index clusterisé, il doit être unique. Mais, SQL Server ne nécessite pas que votre clé de clustering soit créée sur une colonne unique. Vous pouvez le créer sur n'importe quelle colonne que vous souhaitez. En interne, si la clé de clustering n'est pas unique, SQL Server la "uniquifiera" en ajoutant un entier de 4 octets aux données. Donc, si l'index cluster est créé sur quelque chose qui n'est pas unique, il y a non seulement des frais supplémentaires lors de la création de l'index, il y a de l'espace disque gaspillé, des coûts supplémentaires sur les INSERT et les MISES À JOUR, et dans SQL Server 2000, il y a un coût supplémentaire sur un index clustereD reconstruire (ce qui en raison du mauvais choix pour la clé de clustering est maintenant plus probable).

Source: Débat toujours croissant sur les clusters - encore!

25
marc_s

Les index clusterisés doivent-ils être uniques?

Ils ne le font pas, et il y a des moments où c'est mieux s'ils ne le sont pas.

Considérez une table avec un EmployeeId unique et semi-aléatoire et un DepartmentId pour chaque employé: si votre instruction select est

SELECT * FROM EmployeeTable WHERE DepartmentId=%DepartmentValue%

alors il est préférable pour les performances si le DepartmentId est l'index cluster, même si (ou même surtout parce que) ce n'est pas l'index unique (le meilleur pour les performances car il garantit que tous les enregistrements dans un DepartmentId donné sont clusterisés).


Avez-vous des références?

Il y a Clustered Index Design Guidelines par exemple, qui dit,

À quelques exceptions près, chaque table doit avoir un index cluster défini sur la ou les colonnes qui offrent les éléments suivants:

  • Peut être utilisé pour les requêtes fréquemment utilisées.
  • Fournit un haut degré d'unicité.
  • Peut être utilisé dans les requêtes de plage.

Ma compréhension du "haut degré d'unicité", par exemple, est qu'il n'est pas bon de choisir "Pays" comme index sécurisé si la plupart de vos requêtes veulent sélectionner les enregistrements dans une ville donnée.

8
ChrisW