Les INSERT avec une key GUID séquentielle sur un index clusterisé ne sont pas significativement plus rapides

Dans SQL Server 2008, j'ai essayé de reproduire les résultats des expériences sur l'index clusterisé sur les keys GUID séquentielles et non séquentielles vues ici http://sqlblog.com/blogs/denis_gobo/archive/2009/02/05/11743. aspx mais je ne ressens pas l'accélération significative pour les insertions que je m'attendrais (et l'expérience de l'auteur). L'utilisation de la page est clairement améliorée avec le GUID séquentiel, mais pour certaines raisons, l'insertion de 10 000 lignes est seulement environ 100 ms plus rapide (sur 10 300 ms).

J'utilise le code suivant:

CREATE TABLE TestGuid1 (Id UNIQUEIDENTIFIER not null DEFAULT newid(), SomeDate DATETIME, batchNumber BIGINT) CREATE TABLE TestGuid2 (Id UNIQUEIDENTIFIER not null DEFAULT newsequentialid(), SomeDate DATETIME, batchNumber BIGINT) CREATE CLUSTERED INDEX ix_id1 ON TestGuid1(id) CREATE CLUSTERED INDEX ix_id2 ON TestGuid2(id) go SET NOCOUNT ON INSERT TestGuid1 (SomeDate,batchNumber) VALUES (GETDATE(),3) go 10000 SET NOCOUNT ON INSERT TestGuid2 (SomeDate,batchNumber) VALUES (GETDATE(),3) go 10000 DBCC showcontig ('TestGuid1') WITH tableresults DBCC showcontig ('TestGuid2') WITH tableresults SELECT batchNumber,DATEDIFF(ms,MIN(SomeDate),MAX(SomeDate)) FROM TestGuid1 GROUP BY batchNumber SELECT batchNumber,DATEDIFF(ms,MIN(SomeDate),MAX(SomeDate)) FROM TestGuid2 GROUP BY batchNumber 

Quelqu'un peut-il expliquer pourquoi je ne rencontre pas une accélération plus importante pour les insertions sur TestGuid2?

Suivi : Comme demandé dans le fil ci-dessous, j'ai étendu le test: les résultats des tests ont tendance à varier de manière significative au cours du time, maintenant les expériences sont répétées N fois, et l'utilisation du time total et moyen. J'ai également ajouté un troisième test, à savoir pour les keys primaires sur les colonnes entières séquentielles. Cela devrait être le plus rapide et le plus compact des trois methods car le type entier est plus petit et IDENTITY (1,1) est (ou devrait au less être) rapide. Au less par mon intuition. Le time d'exécution moyen est maintenant au bénéfice du GUID séquentiel, mais de manière surprenante, les insertions dans la troisième expérience (avec des keys entières séquentielles) sont plus lentes que les GUID séquentiels. Je n'ai aucune explication de ceci. Voici le code pour les nouvelles expériences:

 SET NOCOUNT ON CREATE TABLE TestGuid1 (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID() PRIMARY KEY, SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100)) CREATE TABLE TestGuid2 (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID() PRIMARY KEY, SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100)) CREATE TABLE TestInt (Id Int NOT NULL identity(1,1) PRIMARY KEY, SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100)) DECLARE @BatchCounter INT = 1 DECLARE @Numrows INT = 100000 WHILE (@BatchCounter <= 20) BEGIN BEGIN TRAN DECLARE @LocalCounter INT = 0 WHILE (@LocalCounter <= @NumRows) BEGIN INSERT TestGuid1 (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter) SET @LocalCounter +=1 END SET @LocalCounter = 0 WHILE (@LocalCounter <= @NumRows) BEGIN INSERT TestGuid2 (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter) SET @LocalCounter +=1 END SET @LocalCounter = 0 WHILE (@LocalCounter <= @NumRows) BEGIN INSERT TestInt (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter) SET @LocalCounter +=1 END SET @BatchCounter +=1 COMMIT END DBCC showcontig ('TestGuid1') WITH tableresults DBCC showcontig ('TestGuid2') WITH tableresults DBCC showcontig ('TestInt') WITH tableresults SELECT batchNumber,DATEDIFF(ms,MIN(SomeDate),MAX(SomeDate)) AS [NEWID()] FROM TestGuid1 GROUP BY batchNumber SELECT batchNumber,DATEDIFF(ms,MIN(SomeDate),MAX(SomeDate)) AS [NEWSEQUENTIALID()] FROM TestGuid2 GROUP BY batchNumber SELECT batchNumber,DATEDIFF(ms,MIN(SomeDate),MAX(SomeDate)) AS [IDENTITY()] FROM TestInt GROUP BY batchNumber DROP TABLE TestGuid1 DROP TABLE TestGuid2 DROP TABLE TestInt 

Et les time d'exécution moyens :

 NEWID() 3064 NEWSEQUENTIALID() 1977 IDENTITY() 2223 

L'utilisation de la page est la suivante:

 Table Pages AveragePageDensity ---------------------------------------- TestGuid1 50871 68,4 TestGuid2 35089 99,2 TestInt 32259 98,7 

Je ne vois pas, pourquoi ces statistics de page (qui sont les meilleures pour TestInt) n'implique pas que l'expérience trois est la plus rapide.

Pouvez-vous essayer ce script modifié et publier vos résultats?

  SET NOCOUNT ON CREATE TABLE TestGuid1 (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID() PRIMARY KEY, SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100)) CREATE TABLE TestGuid2 (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID() PRIMARY KEY, SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100)) DECLARE @BatchCounter INT = 1 WHILE (@BatchCounter <= 20) BEGIN BEGIN TRAN DECLARE @LocalCounter INT = 0 WHILE (@LocalCounter <= 100000) BEGIN INSERT TestGuid1 (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter) SET @LocalCounter +=1 END SET @LocalCounter = 0 WHILE (@LocalCounter <= 100000) BEGIN INSERT TestGuid2 (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter) SET @LocalCounter +=1 END SET @BatchCounter +=1 COMMIT END DBCC showcontig ('TestGuid1') WITH tableresults DBCC showcontig ('TestGuid2') WITH tableresults SELECT batchNumber,DATEDIFF(ms,MIN(SomeDate),MAX(SomeDate)) AS [NEWID()] FROM TestGuid1 GROUP BY batchNumber SELECT batchNumber,DATEDIFF(ms,MIN(SomeDate),MAX(SomeDate)) AS [NEWSEQUENTIALID()] FROM TestGuid2 GROUP BY batchNumber DROP TABLE TestGuid1 DROP TABLE TestGuid2 

Je vois des résultats très différents entre les courses individuelles (sur mon ordinateur portable pas un server!) Mais une tendance définie pour séquentielle d'être plus rapide.

NEWID() Moyenne 5168.9

 batchNumber NEWID() -------------------- ----------- 1 4270 2 2480 3 2706 4 3333 5 7480 6 5346 7 4306 8 7713 9 7313 10 4760 11 4680 12 4113 13 3433 14 2686 15 4963 16 8040 17 5313 18 8160 19 9533 20 2750 

NEWSEQUENTIALID() Moyenne 3000.85

 batchNumber NEWSEQUENTIALID() -------------------- ----------------- 1 2016 2 1820 3 1886 4 1870 5 4873 6 3473 7 3730 8 3690 9 1983 10 2020 11 1906 12 5596 13 2100 14 1950 15 2096 16 1876 17 5196 18 2110 19 2113 20 7713 

Depuis que j'ai écrit cet article de blog original, j'ai décidé d'exécuter votre code, voici ce que je reçois

 3 8726 -- newid() 3 12550 -- newsequantialID 

Rappelez-vous que je l'exécute sur un server avec 32 Go de RAM et 8 processeurs, pas sur un ordinateur portable

sur ma machine locale, je vois presque pas de différence entre les deux

Rappelez-vous, en plus des insertions, les lectures seront beaucoup plus lentes car la table est fragmentée

Voici ce que je reçois en exécutant le script de Martin sur le server

 batchNumber NEWID() 17 1696 19 1706 14 1680 16 1706 5 1660 6 1890 7 1650 8 1663 13 1673 15 1683 2 1656 9 1673 20 1750 1 2033 3 1673 10 1673 12 1670 4 1650 11 1690 18 1696 batchNumber NEWSEQUENTIALID() 2 1276 9 1260 20 1290 13 1266 15 1280 17 1266 19 1266 5 1260 6 1266 7 1260 8 1260 1 1243 3 1256 10 1270 12 1263 14 1266 16 1276 4 1256 11 1270 18 1270 

Voici ce qui se passe sur mon bureau, les files ne sont pas de taille BTW

 batchNumber NEWID() 1 9470 2 4446 3 5996 4 3860 5 4170 6 2403 7 3283 8 3573 9 1883 10 3980 11 2580 12 2780 13 1643 14 2836 15 3250 16 4303 17 3250 18 3376 19 8723 20 2616 batchNumber NEWSEQUENTIALID() 1 2566 2 1336 3 1256 4 3123 5 3023 6 1166 7 2396 8 1180 9 2386 10 3896 11 3790 12 3066 13 1396 14 2010 15 1183 16 3110 17 4060 18 4260 19 1896 20 2013