Ardışık ve ardışık olmayan GUID'leri karşılaştırarak bu soruyu sorduktan sonra , INSERT performansını 1) bir tabloyla sırayla başlatılmış bir GUID birincil anahtarıyla newsequentialid()
ve 2) sıralı bir şekilde başlatılmış bir INT birincil anahtarıyla bir tabloyu karşılaştırmaya çalıştım identity(1,1)
. İkincisinin tamsayıların daha küçük olması nedeniyle en hızlı olmasını beklerdim ve sıralı bir GUID'den sıralı bir tamsayı oluşturmak daha kolay görünüyor. Fakat benim için sürpriz, tamsayı anahtarlı tablodaki INSERT'lerin sıralı GUID tablosundan çok daha yavaştı.
Bu, test çalıştırmaları için ortalama zaman kullanımını (ms) gösterir:
NEWSEQUENTIALID() 1977
IDENTITY() 2223
Bunu kimse açıklayabilir mi?
Aşağıdaki deney kullanıldı:
SET NOCOUNT ON
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 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 ('TestGuid2') WITH tableresults
DBCC showcontig ('TestInt') WITH tableresults
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 TestGuid2
DROP TABLE TestInt
GÜNCELLEME: Aşağıdaki örnekte Phil Sandler, Mitch Wheat ve Martin tarafından yapılan örneklerde olduğu gibi TEMP tablosuna dayalı eklemeleri yapmak için betiği değiştirmek, ayrıca KİMLİK'ün olması gerektiği gibi hızlı olduğunu da biliyorum. Ancak bu satırları eklemek için geleneksel bir yöntem değildir ve hala denemenin ilk başta neden yanlış gittiğini anlamıyorum: orijinal örneğimden GETDATE () atladığım halde IDENTITY () hala çok daha yavaş. Bu yüzden, IDENTITY () 'yi NEWSEQUENTIALID ()' den daha iyi hale getirmenin tek yolu, geçici bir tabloya yerleştirmek için sıraları hazırlamak ve bu geçici tabloyu kullanarak birçok eklemeyi toplu ekleme olarak yapmak gibi görünüyor. Sonuçta, fenomenle ilgili bir açıklama bulduğumuzu sanmıyorum ve IDENTITY () çoğu pratik kullanım için hala daha yavaş görünüyor. Bunu kimse açıklayabilir mi?
INT IDENTITY
IDENTITY
masa kilidi gerektirmez. Kavramsal olarak MAX (id) + 1 almasını beklediğinizi görebiliyordum, ancak gerçekte bir sonraki değer saklanıyor. Aslında bir sonraki GUID'yi bulmaktan daha hızlı olması gerekir.