在SQL Server 2008中,我嘗試從這裏看到的順序與非順序GUID鍵上的聚集索引實驗中重現結果,但我沒有體驗過我期望的插入的顯着加速(以及作者的體驗)。使用連續的GUID可以明顯改善頁面利用率,但由於某些原因,插入10,000行只會快100毫秒(超過10,300毫秒)。在集羣索引上插入順序GUID鍵的速度並不明顯更快
我使用下面的代碼:
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慢。我對此沒有任何解釋。 下面是新的實驗代碼:我看不出
Table Pages AveragePageDensity
----------------------------------------
TestGuid1 50871 68,4
TestGuid2 35089 99,2
TestInt 32259 98,7
:
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
頁用法如下,爲什麼這些頁面統計數據(最適合TestInt)並不意味着實驗三是最快的。
你試過運行裏面的插件顯式交易?目前,所有單獨提交的效果可能會支配結果(順便說一句 - 在'GO'之前放置'BEGIN TRAN'很重要,所以最終不會執行10000次,這將需要相同次數的提交'將@@ TRANCOUNT'降到零) – 2011-05-12 11:22:10
機會是你的樣本量只有10000行很少,表格的重新排序需要SQL服務器這麼短的時間,在任何時候你都不會看到太多的東西一個插入。嘗試將其增加到100,000或1,000,000。在處理這種大小的表格時,聚集索引選擇是一個更有意義的選擇。 – JStead 2011-05-12 11:25:51
Kimberly Tripp在她的博客文章中很好地(並且廣泛地)顯示[磁盤空間便宜 - 這不是**點!](http://www.sqlskills.com/BLOGS/KIMBERLY/post/Disk- space-is-cheap.aspx)多麼糟糕的GUID - 隨機或順序 - 與使用「INT IDENTITY」作爲您表上的羣集索引進行比較 – 2011-05-12 11:26:57