10

Généralement, l'index cluster est créé dans SQL Server Management Studio en définissant la clé primaire, mais ma question récente sur PK < -> clustered index (Meaning of Primary Key to Microsoft SQL Server 2008) a montré qu'il n'est pas nécessaire de définir PK et l'index cluster.Comment choisir l'index cluster dans SQL Server?

Alors, comment devrions-nous choisir les index clusterisés? Ayons l'exemple suivant:

créer table Clients (ID int, ...) créer des commandes de table (ID int, CustomerID int)

Nous généralement créer le PK/CI sur les deux colonnes d'identité, mais i pensé à le créer pour les commandes dans CustomerID. Est-ce le meilleur choix?

+0

Copie possible de [SQL Server - Quand utiliser l'index clusterisé ou non-clusterisé?] (Https://stackoverflow.com/questions/18304376/sql-server-when-to-use-clustered-vs-non- clustered-index) –

Répondre

11

Selon La reine de l'indexation - Kimberly Tripp - ce qu'elle recherche dans un index ordonné en clusters est principalement:

  • unique
  • étroite
  • statique

Et si vous pouvez également garantir:

  • modèle Toujours plus

alors vous êtes assez proche d'avoir votre clé de cluster idéal!

Découvrez son intégralité blog post here, et une autre vraiment intéressante sur les impacts clés de la mise en grappe sur les opérations de table ici: The Clustered Index Debate Continues.

Tout comme un INT (en particulier une INT IDENTITY) ou éventuellement un INT et un DATETIME sont des candiates idéales. Pour d'autres raisons, les GUID ne sont pas du tout des bons candidats - vous pourriez donc avoir un GUID comme PK, mais ne pas mettre votre table en cluster - il sera fragmenté au-delà de la reconnaissance et les performances en souffriront.

+0

Ces articles de blog sont-ils toujours aussi pertinents pour les versions plus récentes de SQL Server, ou ont-ils récemment modifié les meilleures pratiques en modifiant les performances de SQL Server 2008? –

+0

@AdrianGrigore: tout est toujours valide, du moment que vous utilisez des tables "normales" (par exemple, pas des archives de datawarehouse/columnstore) –

+0

Super, merci! :) –

1

Si vous êtes préoccupé par la mise en cluster, c'est généralement pour aider à améliorer la récupération des données. Dans votre exemple, vous allez probablement vouloir tous les enregistrements pour un client donné à la fois. Le regroupement sur customerID conservera ces lignes sur la même page physique plutôt que sur plusieurs pages de votre fichier. ROT: cluster sur ce que vous voulez montrer une collection de. Les éléments de campagne d'une commande sont l'exemple classique.

+0

Les éléments de ligne d'un bon de commande peuvent être une bonne idée pour un cluster, mais pas s'il y a seulement deux ou trois (ou une douzaine) éléments de campagne sur l'ordre type. À moins que les lignes que vous regroupez commencent à entrer dans les dizaines ou les centaines, il est préférable de laisser SQL Server effectuer la recherche de signet. J'avais un système où les besoins de l'entreprise devaient trouver tous les «éléments de ligne» qui se sont produits pendant le quart d'un caissier particulier (pour voir s'ils étaient équilibrés). Dénormaliser les "éléments de ligne" avec le "id" si le ** Shift **, puis en cluster sur ** Shift ** était un énorme coup de pouce de vitesse. –

6

Le meilleur candidat pour un index CLUSTERED est la clé que vous utilisez pour faire référence à vos enregistrements le plus souvent.

Généralement, il s'agit d'un PRIMARY KEY, puisqu'il est utilisé dans les recherches et/ou les relations FOREIGN KEY.

Dans votre cas, Orders.ID participera probablement aux recherches et aux références, c'est donc le meilleur candidat pour être une expression de clustering.

Si vous créez l'index CLUSTERED sur Orders.CustomerID, les choses suivantes se produiront:

  1. CustomerID est pas unique. Pour assurer l'unicité, une colonne 32-bit cachée spéciale appelée uniquifier sera ajoutée à chaque enregistrement.

  2. Les enregistrements de la table seront stockés conformément à cette paire de colonnes (CustomerID, uniquifier). Un index secondaire sur Order.ID sera créé avec (CustomerID, uniquifier) comme pointeurs d'enregistrement.

  3. requêtes comme celle-ci:

    SELECT * 
    FROM Orders 
    WHERE ID = 1234567 
    

    devront faire une opération externe, un Clustered Seek, car toutes les colonnes sont stockées dans l'index sur ID. Pour récupérer toutes les colonnes, l'enregistrement doit d'abord se trouver dans la table en cluster.

Cette opération supplémentaire nécessite IndexDepth autant de pages se lit comme un Clustered Seek simple, le IndexDepth beign O(log(n)) du nombre total des enregistrements de votre table.

Questions connexes