Setelah mengajukan pertanyaan ini membandingkan GUID berurutan dan non-berurutan, saya mencoba membandingkan kinerja INSERT pada 1) tabel dengan kunci primer GUID yang diinisialisasi secara berurutan newsequentialid()
, dan 2) tabel dengan kunci primer INT yang diinisialisasi secara berurutan identity(1,1)
. Saya berharap yang terakhir menjadi yang tercepat karena lebar integer yang lebih kecil, dan juga tampaknya lebih mudah untuk menghasilkan integer berurutan daripada GUID berurutan. Tapi yang mengejutkan saya, INSERT di atas meja dengan kunci integer secara signifikan lebih lambat daripada tabel GUID berurutan.
Ini menunjukkan penggunaan waktu rata-rata (ms) untuk pengujian berjalan:
NEWSEQUENTIALID() 1977
IDENTITY() 2223
Adakah yang bisa menjelaskan ini?
Eksperimen berikut digunakan:
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
UPDATE: Memodifikasi skrip untuk melakukan penyisipan berdasarkan tabel TEMP, seperti dalam contoh oleh Phil Sandler, Mitch Wheat dan Martin di bawah ini, saya juga menemukan bahwa IDENTITAS lebih cepat sebagaimana mestinya. Tapi itu bukan cara konvensional memasukkan baris, dan saya masih tidak mengerti mengapa percobaan itu salah pada awalnya: bahkan jika saya menghilangkan GETDATE () dari contoh asli saya, IDENTITY () masih jauh lebih lambat. Jadi sepertinya satu-satunya cara untuk membuat IDENTITY () mengungguli NEWSEQUENTIALID () adalah menyiapkan baris untuk dimasukkan dalam tabel sementara dan melakukan banyak penyisipan sebagai penyisipan batch menggunakan tabel temp ini. Secara keseluruhan, saya tidak berpikir kami telah menemukan penjelasan tentang fenomena tersebut, dan IDENTITY () tampaknya masih lebih lambat untuk sebagian besar penggunaan praktis. Adakah yang bisa menjelaskan ini?
INT IDENTITY
IDENTITY
tidak memerlukan kunci tabel. Secara konseptual saya bisa melihat Anda mungkin mengharapkannya mengambil MAX (id) +1, tetapi pada kenyataannya nilai selanjutnya disimpan. Ini sebenarnya harus lebih cepat daripada menemukan GUID berikutnya.