Question

Je travaille sur une base de données qui utilise généralement des GUID en tant que clés primaires.

Par défaut, SQL Server place un index en cluster sur les colonnes de clé primaire. Je comprends que c’est une idée stupide pour les colonnes GUID et que les index non clusterisés sont meilleurs.

Que pensez-vous - devrais-je me débarrasser de tous les index clusterisés et les remplacer par des index non clusterisés?

Pourquoi l'optimiseur de performances de SQL ne propose-t-il pas cela comme recommandation?

Était-ce utile?

La solution

Une raison importante pour un index en cluster est lorsque vous souhaitez souvent récupérer des lignes pour une plage de valeurs pour une colonne donnée. Les données étant physiquement classées dans cet ordre, les lignes peuvent être extraites très efficacement.

Quelque chose comme un GUID, bien qu’excellent pour une clé primaire, pourrait nuire de façon significative aux performances, car il y aura un coût supplémentaire pour les insertions et aucun avantage perceptible sur certains éléments sélectionnés.

Alors oui, ne mettez pas en cluster un index sur le GUID.

En ce qui concerne la raison pour laquelle ce n'est pas proposé comme recommandation, je suggérerais que le syntoniseur soit conscient de ce fait.

Autres conseils

Vous souhaiterez presque certainement établir un index clusterisé sur chaque table de votre base de données. Si une table n’a pas d’indice en cluster, c’est ce que l’on appelle un "tas". et les performances de la plupart des types de requêtes courantes sont moins pour un tas que pour un index en cluster tableau .

Les champs sur lesquels l'index clusterisé doit être établi dépendent de la table elle-même et des modèles d'utilisation attendus des requêtes sur la table. Dans presque tous les cas, vous voudrez probablement que l'index clusterisé se trouve sur une colonne ou une combinaison de colonnes unique, c'est-à-dire (une clé alternative), car sinon, SQL ajoutera une valeur unique à la fin de n'importe quoi. champs que vous sélectionnez quand même. Si votre table contient une colonne ou des colonnes qui seront fréquemment utilisées par les requêtes pour sélectionner ou filtrer plusieurs enregistrements (par exemple, si votre table contient des transactions de vente et que votre application demandera fréquemment des transactions de vente par ID de produit, voire mieux, une table de détail des factures, dans laquelle vous récupérerez dans la quasi-totalité des cas tous les enregistrements de détails d'une facture spécifique, ou une table de factures dans laquelle vous récupérerez souvent toutes les factures d'un client particulier ... Cela est vrai que vous soyez sélectionné en grand nombre d'enregistrements par une valeur unique ou par une plage de valeurs)

Ces colonnes sont des candidats pour l'index clusterisé. L'ordre des colonnes dans l'index clusterisé est critique. La première colonne définie dans l'index doit être celle qui sera sélectionnée ou filtrée lors de la première requête dans les requêtes attendues.

La raison de tout cela est basée sur la compréhension de la structure interne d’un index de base de données. Ces indices sont appelés indices d'arborescence équilibrée (B-Tree). ils ressemblent un peu à une arborescence binaire, sauf que chaque nœud de l'arborescence peut avoir un nombre arbitraire d'entrées (et de nœuds enfants) au lieu de deux. Ce qui différencie un index clusterisé est que les nœuds d'extrémité d'un index clusterisé sont les pages de données de disque physique réelles de la table elle-même. alors que les noeuds feuilles de l'index non-cluster viennent juste de "pointer" aux pages de données des tables.

Quand une table a un index clusterisé, les pages de données des tables sont donc le niveau feuille de cet index, et chacune d’elles a un pointeur sur la page précédente et la page suivante dans l’ordre des index (elles forment un lien doublement lié). -liste).

Ainsi, si votre requête demande une plage de lignes dans le même ordre que l’index clusterisé ... le processeur n’a à parcourir l’index qu’une seule fois (ou peut-être deux fois) pour trouver la page de démarrage des données et suivez ensuite les pointeurs de liste liés pour accéder à la page suivante et à la page suivante, jusqu'à ce qu'il ait lu toutes les pages de données dont il a besoin.

Pour un index non clusterisé, il doit traverser l'index une fois pour chaque ligne récupérée ...

REMARQUE: MODIFIER
Pour résoudre le problème séquentiel des colonnes Guid Key, sachez que SQL2k5 a NEWSEQUENTIALID () qui génère en fait des Guids les "anciens". manière séquentielle.

ou vous pouvez rechercher un algorithme de contrôle COMB Jimmy Nielsens qui est implémenté dans le code côté client:

GUID COMB

Le problème avec les index clusterisés dans un champ GUID est que les GUID sont aléatoires. Ainsi, lorsqu'un nouvel enregistrement est inséré, une partie importante des données sur le disque doit être déplacée pour insérer les enregistrements au milieu de la table.

Cependant, avec les index clusterisés basés sur des entiers, les entiers sont normalement séquentiels (comme avec une spécification IDENTITY ), de sorte qu'ils sont simplement ajoutés à la fin et qu'aucune donnée ne doit être déplacée. / p>

D'un autre côté, les index clusterisés ne sont pas toujours mauvais sur les GUID ... tout dépend des besoins de votre application. Si vous avez besoin de pouvoir SELECT enregistrer rapidement, utilisez un index clusterisé ... la vitesse INSERT en souffrira, mais la vitesse SELECT sera amélioré.

Si vous utilisez NewId (), vous pouvez passer à NewSequentialId (). Cela devrait aider la performance d'insertion.

Oui, il est inutile d'avoir un index clusterisé sur une valeur aléatoire.

Vous voulez probablement des index clusterisés QUELQUE PART dans votre base de données. Par exemple, si vous avez un " Auteur " table et un "livre" table avec une clé étrangère à "Auteur", et si votre demande contient une requête qui dit: "sélectionnez ... dans le livre où AuthorId = ..", vous liriez alors un ensemble de livres. Ce sera plus rapide si ces livres sont physiquement côte à côte sur le disque, de sorte que la tête de disque n'ait pas à rebondir d'un secteur à l'autre pour rassembler tous les livres de cet auteur.

Vous devez donc réfléchir à votre application, à la manière dont elle interroge la base de données.

Apportez les modifications.

Et puis testez, car vous ne savez jamais ...

Oui, vous devez supprimer l'index clusterisé sur les clés primaires GUID pour les raisons indiquées ci-dessus. Nous l'avons fait sur nos applications.

Cela dépend si vous faites beaucoup d'inserts ou si vous avez besoin d'une recherche très rapide par PK.

Comme la plupart des personnes l'ont mentionné, évitez d'utiliser un identifiant aléatoire dans un index clusterisé: vous ne bénéficierez pas des avantages de la mise en cluster. En fait, vous allez connaître un délai accru. Se débarrasser de tous est un conseil solide. N'oubliez pas non plus que newsequentialid () peut être extrêmement problématique dans un scénario de réplication multimaître. Si les bases de données A et B invoquent toutes deux newsequentialid () avant la réplication, vous aurez un conflit.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top