J'ai une application qui utilise le GUID comme clé primaire dans presque toutes les tables et j'ai lu qu'il y a des problèmes de performances lors de l'utilisation du GUID comme clé primaire. Honnêtement, je n'ai vu aucun problème, mais je suis sur le point de démarrer une nouvelle application et je veux toujours utiliser les GUID comme clés primaires, mais je pensais utiliser une clé primaire composite (le GUID et peut-être un autre champ .)
J'utilise un GUID car ils sont agréables et faciles à gérer lorsque vous avez différents environnements tels que les bases de données "production", "test" et "dev", ainsi que pour les données de migration entre les bases de données.
J'utiliserai Entity Framework 4.3 et je veux attribuer le Guid dans le code d'application, avant de l'insérer dans la base de données. (c'est-à-dire que je ne veux pas laisser SQL générer le Guid).
Quelle est la meilleure pratique pour créer des clés primaires basées sur GUID, afin d'éviter les supposés résultats de performance associés à cette approche?
Réponses:
Les GUID peuvent sembler être un choix naturel pour votre clé primaire - et si vous le devez vraiment, vous pourriez probablement argumenter pour l'utiliser pour la CLÉ PRIMAIRE de la table. Ce que je recommande fortement de ne pas faire, c'est d'utiliser la colonne GUID comme clé de clustering , ce que SQL Server fait par défaut, sauf si vous le lui dites expressément.
Vous devez vraiment séparer deux problèmes:
la clé primaire est une construction logique - l'une des clés candidates qui identifie de manière unique et fiable chaque ligne de votre table. Cela peut être n'importe quoi, vraiment - une
INT
, uneGUID
, une chaîne - choisissez ce qui a le plus de sens pour votre scénario.la clé de clustering (la ou les colonnes qui définissent l '"index clusterisé" sur la table) - c'est une chose liée au stockage physique , et ici, un petit type de données stable et en constante augmentation est votre meilleur choix -
INT
ouBIGINT
comme votre option par défaut.Par défaut, la clé primaire d'une table SQL Server est également utilisée comme clé de cluster - mais cela n'a pas besoin d'être ainsi! J'ai personnellement constaté des gains de performances massifs lors de la division de la clé primaire / cluster basée sur GUID précédente en deux clés distinctes - la clé primaire (logique) sur le GUID et la clé de clustering (commande) sur une
INT IDENTITY(1,1)
colonne distincte .Comme Kimberly Tripp - la reine de l'indexation - et d'autres l'ont dit à maintes reprises -
GUID
car la clé de clustering n'est pas optimale, car en raison de son caractère aléatoire, elle entraînera une fragmentation massive des pages et des index et des performances généralement mauvaises.Oui, je sais - il y a
newsequentialid()
dans SQL Server 2005 et plus - mais même cela n'est pas vraiment et entièrement séquentiel et souffre donc également des mêmes problèmes que leGUID
- un peu moins bien en évidence.Ensuite, il y a un autre problème à considérer: la clé de clustering d'une table sera ajoutée à chaque entrée de chaque index non clusterisé de votre table également - vous devez donc vraiment vous assurer qu'elle est aussi petite que possible. En règle générale, un
INT
avec plus de 2 milliards de lignes devrait être suffisant pour la grande majorité des tables - et par rapport à unGUID
comme clé de clustering, vous pouvez vous épargner des centaines de mégaoctets de stockage sur disque et dans la mémoire du serveur.Calcul rapide - en utilisant
INT
vsGUID
comme clé principale et de clustering:TOTAL: 25 Mo contre 106 Mo - et ce n'est que sur une seule table!
Un peu plus de matière à réflexion - d'excellentes choses par Kimberly Tripp - lisez-le, relisez-le, digérez-le! C'est vraiment l'évangile d'indexation de SQL Server.
PS: bien sûr, si vous ne traitez qu'avec quelques centaines ou quelques milliers de lignes - la plupart de ces arguments n'auront pas vraiment d'impact sur vous. Cependant: si vous entrez dans les dizaines ou les centaines de milliers de lignes, ou si vous commencez à compter des millions - alors ces points deviennent très cruciaux et très importants à comprendre.
Mise à jour: si vous voulez avoir votre
PKGUID
colonne comme clé primaire (mais pas votre clé de cluster), et une autre colonneMYINT
(INT IDENTITY
) comme clé de cluster - utilisez ceci:Fondamentalement: il vous suffit de dire explicitement à la
PRIMARY KEY
contrainte qu'elle estNONCLUSTERED
(sinon elle est créée en tant qu'index cluster, par défaut) - puis vous créez un deuxième index défini commeCLUSTERED
Cela fonctionnera - et c'est une option valable si vous avez un système existant qui doit être "repensé" pour des performances. Pour un nouveau système, si vous partez de zéro et que vous n'êtes pas dans un scénario de réplication, je choisirais toujours
ID INT IDENTITY(1,1)
ma clé primaire en cluster - beaucoup plus efficace qu'autre chose!la source
DATETIME
par exemple ne sont PAS utiles pour une clé de clustering, car elles ont une précision de 3,33 ms seulement, et donc des doublons peuvent exister. Donc, dans un tel cas, vous * avez toujours besoin d'un à laINT IDENTITY
place - par conséquent, j'utilise généralement cela par défaut, depuis frmo mes 20+ années d'expérience, une clé naturelle vraiment utilisable n'existe presque jamais vraiment ....J'utilise des GUID comme PK depuis 2005. Dans ce monde de bases de données distribuées, c'est absolument la meilleure façon de fusionner des données distribuées. Vous pouvez déclencher et oublier les tables de fusion sans vous soucier de la correspondance des entiers entre les tables jointes. Les jointures GUID peuvent être copiées sans aucun souci.
Voici ma configuration pour l'utilisation des GUID:
PK = GUID. Les GUID sont indexés de la même manière que les chaînes, de sorte que les tables de lignes hautes (plus de 50 millions d'enregistrements) peuvent nécessiter un partitionnement de table ou d'autres techniques de performances. SQL Server devient extrêmement efficace, donc les problèmes de performances sont de moins en moins applicables.
PK Guid est un indice NON clusterisé. N'indexez jamais un GUID en cluster, sauf s'il s'agit de NewSequentialID. Mais même dans ce cas, un redémarrage du serveur entraînera des interruptions importantes dans la commande.
Ajoutez ClusterID Int à chaque table. C'est votre index CLUSTERED ... qui commande votre table.
La jointure sur ClusterIDs (int) est plus efficace, mais je travaille avec 20-30 millions de tables d'enregistrement, donc la jointure sur GUIDs n'affecte pas visiblement les performances. Si vous voulez des performances maximales, utilisez le concept ClusterID comme clé primaire et rejoignez ClusterID.
Voici ma table d'email ...
la source
Je développe actuellement une application web avec EF Core et voici le schéma que j'utilise:
Toutes mes classes (tables) et un int PK et FK. J'ai une colonne supplémentaire avec le type Guid (généré par le constructeur c #) avec un index non clusterisé dessus.
Toutes les jointures de table dans EF sont gérées via les clés int tandis que tous les accès depuis l'extérieur (contrôleurs) se font avec les Guids.
Cette solution permet de ne pas afficher les clés int sur les URL mais de garder le modèle rangé et rapide.
la source
Si vous utilisez le GUID comme clé primaire et créez un index clusterisé, je suggère d'utiliser la valeur par défaut NEWSEQUENTIALID () pour cela
la source
Ce lien le dit mieux que moi et m'a aidé dans ma prise de décision. J'utilise généralement un int comme clé primaire, sauf si j'ai un besoin spécifique de ne pas le faire et je laisse également le serveur SQL générer / maintenir automatiquement ce champ, sauf si j'ai une raison spécifique de ne pas le faire. En réalité, les problèmes de performances doivent être déterminés en fonction de votre application spécifique. Il existe de nombreux facteurs en jeu ici, mais sans s'y limiter, la taille de base de données attendue, une indexation appropriée, une interrogation efficace, etc. Bien que les gens puissent être en désaccord, je pense que dans de nombreux scénarios, vous ne remarquerez pas de différence avec l'une ou l'autre option et vous devriez choisir ce qui est le plus approprié pour votre application et ce qui vous permet de développer plus facilement, plus rapidement et plus efficacement (si vous ne terminez jamais l'application quelle différence le reste fait :).
https://web.archive.org/web/20120812080710/http://databases.aspfaq.com/database/what-should-i-choose-for-my-primary-key.html
PS Je ne sais pas pourquoi vous utiliseriez un PK composite ou quel avantage vous pensez que cela vous apporterait.
la source
La plupart du temps, il ne doit pas être utilisé comme clé primaire pour une table car cela affecte vraiment les performances de la base de données. liens utiles concernant l'impact du GUID sur les performances et en tant que clé primaire.
la source
Le fait d'avoir des identifiants séquentiels rend beaucoup plus facile pour un pirate ou un mineur de données de compromettre votre site et vos données. Gardez cela à l'esprit lorsque vous choisissez un PK pour un site Web.
la source