在SQL Server 2008中,我尝试重现来自顺序索引和非顺序GUID密钥的聚集索引的实验结果,此处的 http://sqlblog.com/blogs/denis_gobo/archive/2009/02/05/11743。 aspx, 但我并没有体验到我期望的(和作者所体验到的)插入速度的显着提高。顺序GUID明显提高了页面利用率,但是由于某些原因,插入10,000行仅快100毫秒左右(10,300毫秒中)。
我使用以下代码:
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
谁能解释为什么我在TestGuid2上没有更快的插入速度?
后续 : 按照 下面线程中的要求,我扩大了测试范围:测试结果倾向于随时间变化很大,因此现在将实验重复N次,并报告总和平均使用时间。我还添加了第三项测试,即针对顺序整数列上的主键。这应该是这三种方法中最快,最紧凑的,因为整数类型较小并且IDENTITY(1,1)快(或至少应该快)。至少根据我的直觉。现在, 平均 执行时间有益于顺序GUID,但是令人惊讶的是,在第三个实验中(使用顺序整数键)插入的 速度 比顺序GUID 慢 。我对此没有任何解释。这是新实验的代码:
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
而 平均 执行时间:
NEWID() 3064 NEWSEQUENTIALID() 1977 IDENTITY() 2223
页面用法如下:
Table Pages AveragePageDensity ---------------------------------------- TestGuid1 50871 68,4 TestGuid2 35089 99,2 TestInt 32259 98,7
我看不到,为什么这些网页统计信息(最适合TestInt)并不意味着实验3最快。
您可以尝试修改后的脚本并发布结果吗?
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
我发现各个运行之间的结果差异很大(在我的笔记本电脑上而不是服务器上!),但是连续运行的明显趋势是更快。
NEWID() 均值5168.9
NEWID()
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() 均值3000.85
NEWSEQUENTIALID()
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