Question

Jusqu'à maintenant, je me sers du C # "Guid = Guid.NewGuid ();" méthode pour générer un identifiant unique qui peut être stocké comme champ d'identification dans certaines de mes tables de base de données SQL Server à l'aide LINQ to SQL. J'ai été informé que pour des raisons d'indexation, en utilisant un GUID est une mauvaise idée et que je devrais utiliser un auto-incrémentée longue à la place. Est-ce que l'aide d'une longue vitesse mes transactions de base de données? Si oui, comment puis-je faire pour générer des ID uniques qui sont de type long?

Cordialement,

Était-ce utile?

La solution

Les deux ont des avantages et des inconvénients, cela dépend entièrement de la façon dont vous les utilisez que les questions.

Dès le départ, si vous avez besoin des identifiants qui peuvent travailler dans plusieurs bases de données, vous avez besoin GUIDs. Il y a quelques trucs avec Long (attribuer manuellement chaque base de données une graine / incrément différent), mais ceux-ci n'échelle pas bien.

En ce qui concerne l'indexation va, Long donnera de meilleures performances d'insertion si l'indice est agglomérat (par les clés primaires par défaut sont regroupés, mais cela peut être modifié pour votre table), étant donné que la table n'a pas besoin d'être réorganisée après chaque insérer.

En ce qui concerne les insertions concurrentes sont cependant longues (identité) colonnes sera plus lente alors GUID - génération de colonne d'identité nécessite une série de verrous exclusifs pour assurer qu'une seule ligne obtient le numéro séquentiel suivant. Dans un environnement avec de nombreux utilisateurs pour insérer plusieurs lignes tout le temps, cela peut être un coup de performance. génération GUID dans cette situation est plus rapide.

Stockage sage, un GUID reprend deux fois l'espace d'un long (8 octets vs 16). Cependant, il dépend de la taille globale de votre ligne si 8 octets va faire une différence notable dans le nombre d'enregistrements dans une feuille s'adapter, et donc le nombre de feuilles tiré à partir du disque lors d'une demande moyenne.

Autres conseils

Une longue (grand int dans le serveur SQL) est de 8 octets et un Guid est de 16 octets, donc vous réduire de moitié le nombre des octets serveur SQL doit comparer lorsque vous faites un coup d'oeil vers le haut.

Pour générer une longue utilisation IDENTITÉ (1,1) lorsque vous créez le champ dans la base de données.

donc soit en utilisant la table de créer ou de modifier le tableau:

Field_NAME BIGINT NOT NULL PRIMARY KEY IDENTITY(1,1)

Voir les commentaires pour l'affichage LINQ to SQL

La "reine d'indexation" - Kim Tripp - dit fondamentalement tout dans son messages blog d'indexation:

En fait, ses meilleures pratiques sont: une clé de cluster optimale doit être:

  • unique,
  • petit
  • stable (jamais changer)
  • sans cesse croissant

GUID violent le « petit » et « toujours plus » et ne sont donc pas optimales.

PLUS: toutes vos clés de regroupement seront ajoutés à chaque entrée unique dans chaque et chaque index non cluster (comme la recherche pour trouver réellement l'enregistrement dans la base de données), ainsi que vous voulez les faire le plus petit possible (INT = 4 octets par rapport GUID = 16 octets). Si vous avez des centaines de millions de lignes et plusieurs indices non groupés, le choix d'un INT ou BIGINT sur un GUID peut faire une grande différence -. Même juste l'espace sage

Marc

Utilisez GUIDs lorsque vous devez considérer l'importation / l'exportation vers plusieurs bases de données. Guids sont souvent plus faciles à utiliser que des colonnes spécifiant l'attribut IDENTITY lorsque vous travaillez avec un ensemble de données multiples relations enfants. c'est parce que vous pouvez générer au hasard GUIDs dans le code dans un état déconnecté de la base de données, puis soumettre toutes les modifications à la fois. Lorsque GUIDs sont générés correctement, ils sont difficiles à reproduire insainely par hasard. Avec des colonnes d'identité, vous avez souvent à faire un insert intial d'une ligne de parent et d'interrogation pour sa nouvelle identité avant d'ajouter des données de l'enfant. Vous devez alors mettre à jour tous les dossiers des enfants avec la nouvelle identité de parent avant de les engager dans la base de données. La même chose vaut pour les petits-enfants et ainsi de suite de la hiérarchie. Il construit jusqu'à beaucoup de travail qui semble inutile et banal. Vous pouvez faire quelque chose de similaire à Guids par comming avec des entiers aléatoires sans la spécification identité, mais le risque de collision est considérablement augmenté lorsque vous insérez plusieurs enregistrements au fil du temps. (Guid.NewGuid () est similaire à un Int128 aléatoire - qui n'existe pas encore).

J'utilise octet (TinyInt), Int16 (SmallInt), Int32 / UInt16 (Int), Int64 / UInt32 (BigInt) pour les petites listes de recherche qui ne changent pas ou de données qui ne se réplique pas entre plusieurs bases de données. (autorisations de configuration, l'application, des noms de couleurs, etc.)

J'imagine que l'indexation prend aussi longtemps pour interroger contre, peu importe si vous utilisez un guid ou une longue. Il y a habituellement d'autres champs dans les tableaux qui sont indexés qui sont plus grandes que 128 bits de toute façon (noms d'utilisateur dans une table utilisateur par exemple). La différence entre Guids et Entiers est la taille de l'index en mémoire, ainsi que le temps et la reconstruction des index peuplant. La majorité des transactions de base de données est en train de lire souvent. L'écriture est minime. Se concentrer sur l'optimisation de la lecture de la première base de données, car ils sont généralement faits de tables jointes qui ne sont pas optimisés correctement, la pagination incorrecte ou index manquants.

Comme quoi que ce soit, la meilleure chose à faire est de prouver votre point. créer une base de données de test avec deux tables. Une avec une clé primaire des entiers / désire ardemment, et l'autre avec un guid. Remplir chaque avec du N-million de lignes. Moniter la performance de chaque au cours des opérations de CRUD (créer, lire, mettre à jour, suppression). Vous pouvez savoir qu'il a un impact sur les performances, mais insignifiante.

Les serveurs fonctionnent souvent sur des boîtes sans débogage des environnements et d'autres applications prenant CPU, mémoire et E / S du disque dur (en particulier avec RAID). Un environnement de développement que vous donne une idée de la performance.

Vous pouvez débattre GUID ou identité toute la journée. Je préfère la base de données pour générer la valeur unique avec une identité. Si vous fusionnez les données à partir de plusieurs bases de données, ajouter une autre colonne (pour identifier la base de données source, peut-être un ou tinyint smallint) et forment une clé primaire composite.

Si vous allez avec une identité, assurez-vous de choisir le bon type de données, en fonction du nombre de clés attendus que vous allez générer:

bigint - 8 Bytes - max positive value: 9,223,372,036,854,775,807  
int    - 4 Bytes - max positive value:             2,147,483,647

Note « nombre de clés attendus » est différent du nombre de lignes. Si vous ajoutez principalement et de garder les lignes, vous pouvez constater que l'INT est assez avec plus de 2 milliards clés uniques. Je parie que votre table ne sera pas obtenir ce grand. Toutefois, si vous avez une grande table de volume où vous continuez à ajouter et suppression de lignes, vous le nombre de lignes peut être faible, mais vous passerez par les touches rapides. Vous devez faire quelques calculs pour voir comment se connecter, il faudrait passer par les interceptions 2 milliards de clés. Si ce sera pas les utiliser rapidement en tout temps avec INT, sinon le double de la taille de la clé et aller avec BIGINT.

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