Question

Je suis en train de comprendre comment guid séquentiel effectue mieux qu'un guid régulier.

Est-ce parce qu'avec guid régulière, l'indice utilise le dernier octet du guid de sorte? Comme il est aléatoire, il causera beaucoup de fragmentation et fractionnements, car il se déplace souvent des données vers une autre page pour insérer de nouvelles données?

séquentiel guid sinus est séquentielle, il provoque des ruptures de page beaucoup moins et la fragmentation?

est que je comprends bien?

Si quelqu'un peut jeter plus de lumière sur le sujet, j'apprécie beaucoup.

Merci

EDIT:

Sequential guid = NEWSEQUENTIALID ()

Regular guid = NEWID ()

Était-ce utile?

La solution

Vous avez à peu près tout dit dans votre question.

Avec un séquentiel GUID / primaire de nouvelles lignes clés seront additionnés à la fin de la table, ce qui rend agréable choses facile pour le serveur SQL. En comparaison un moyen de clé primaire au hasard que les nouveaux dossiers pourraient être insérés partout dans la table - la chance de la dernière page de la table étant dans le cache est assez probable (si c'est où toutes les lectures sont en cours), mais la chance de une page au hasard au milieu de la table étant dans le cache est assez faible, ce qui signifie IO est nécessaire.

En plus de cela, lors de l'insertion des lignes dans le milieu de la table il y a la chance qu'il n'y a pas assez de place pour insérer la ligne supplémentaire. Si tel est le cas, alors les besoins SQL serveur pour effectuer des opérations coûteuses IO supplémentaires afin de créer un espace pour l'enregistrement - la seule façon d'éviter cela est d'avoir des lacunes, disséminées dans les données pour permettre des enregistrements supplémentaires à insérer (connu sous le nom facteur de remplissage), ce qui en soi provoque des problèmes de performance car les données sont réparties sur plusieurs pages et donc plus IO est nécessaire pour accéder à la table entière.

Autres conseils

Je remets à la sagesse de Kimberly L. Tripp sur ce sujet:

  

Mais, un GUID qui n'est pas séquentielle -   comme celui qui a des valeurs de it   générée dans le client (à l'aide NET)   Ou généré par la fonction newid ()   (Dans SQL Server) peut être un horriblement mauvais   choix - principalement en raison de la   la fragmentation qu'il crée dans la   Base de table, mais aussi en raison de sa   Taille. Il est inutilement large (il est 4   fois plus large qu'une identité basée int-   - qui peut vous donner 2 milliards (vraiment, 4 milliards) lignes uniques). Et,   si vous avez besoin de plus de 2 milliards de vous   peut toujours aller avec un BIGINT (8 octets   int) et obtenir 263-1 lignes.

En savoir plus: http://www.sqlskills.com/BLOGS/KIMBERLY/post/GUIDs-as-PRIMARY-KEYs-andor-the-clustering-key.aspx#ixzz0wDK6cece

Pour visualiser l'image entière util nommé OSTRESS peut être utilisé. Par exemple. vous pouvez créer deux tables: l'une avec normale GUID comme PK, un autre avec GUID séquentiel:

-- normal one
CREATE TABLE dbo.YourTable(
   [id] [uniqueidentifier] NOT NULL,
   CONSTRAINT [PK_YourTable] PRIMARY KEY NONCLUSTERED (id)
);
-- sequential one
CREATE TABLE dbo.YourTableSeq(
   [id] [uniqueidentifier] NOT NULL CONSTRAINT [df_yourtable_id]  DEFAULT (newsequentialid()),
   CONSTRAINT [PK_YourTableSeq] PRIMARY KEY NONCLUSTERED (id)
);

Ensuite, avec une donnée util vous exécutez un numbero d'inserts avec une sélection de statistiques sur la fragmentation de l'index:

ostress -Slocalhost -E -dYourDB -Q"INSERT INTO dbo.YourTable VALUES (NEWID()); SELECT count(*) AS Cnt FROM dbo.YourTable; SELECT AVG_FRAGMENTATION_IN_PERCENT AS AvgPageFragmentation, PAGE_COUNT AS PageCounts FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, N'LIMITED') DPS INNER JOIN sysindexes SI ON DPS.OBJECT_ID = SI.ID AND DPS.INDEX_ID = SI.INDID WHERE SI.NAME = 'PK_YourTable';" -oE:\incoming\TMP\ -n1 -r10000

ostress -Slocalhost -E -dYourDB -Q"INSERT INTO dbo.YourTableSeq DEFAULT VALUES; SELECT count(*) AS Cnt FROM dbo.YourTableSeq; SELECT AVG_FRAGMENTATION_IN_PERCENT AS AvgPageFragmentation, PAGE_COUNT AS PageCounts FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, N'LIMITED') DPS INNER JOIN sysindexes SI ON DPS.OBJECT_ID = SI.ID AND DPS.INDEX_ID = SI.INDID WHERE SI.NAME = 'PK_YourTableSeq';" -oE:\incoming\TMP\ -n1 -r10000

Ensuite, dans le fichier E: \ entrant \ TMP \ query.out vous trouverez vos statistiques. Mes résultats sont les suivants:

"Normal" GUID:
Records    AvgPageFragmentation     PageCounts           
---------------------------------------------- 
1000       87.5                     8                    
2000       93.75                    16                   
3000       96.15384615384616        26                   
4000       96.875                   32                   
5000       96.969696969696969       33                   
10000      98.571428571428584       70                   


Sequential GUID:
Records    AvgPageFragmentation     PageCounts           
---------------------------------------------- 
1000       83.333333333333343       6                    
2000       63.636363636363633       11                   
3000       41.17647058823529        17                   
4000       31.818181818181817       22                   
5000       25.0                     28                   
10000      12.727272727272727       55       

Comme vous pouvez le voir avec GUID généré de manière séquentielle étant insérée, l'indice est beaucoup moins fragmenté que les fils d'opération d'insertion à nouveau plus rare allocation de pages.

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