Sau khi đặt câu hỏi này để so sánh các GUID tuần tự và không tuần tự, tôi đã thử so sánh hiệu suất INSERT trên 1) một bảng với khóa chính GUID được khởi tạo tuần tự với newsequentialid()
và 2) một bảng có khóa chính INT được khởi tạo tuần tự với identity(1,1)
. Tôi hy vọng cái sau sẽ nhanh nhất vì độ rộng của số nguyên nhỏ hơn và việc tạo một số nguyên tuần tự có vẻ đơn giản hơn so với GUID tuần tự. Nhưng thật ngạc nhiên, các INSERT trên bảng có khóa số nguyên chậm hơn đáng kể so với bảng GUID tuần tự.
Điều này cho thấy thời gian sử dụng trung bình (ms) cho các lần chạy thử:
NEWSEQUENTIALID() 1977
IDENTITY() 2223
Bất cứ ai có thể giải thích điều này?
Thí nghiệm sau đây đã được sử dụng:
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
CẬP NHẬT: Sửa đổi tập lệnh để thực hiện các phần chèn thêm dựa trên bảng TEMP, như trong các ví dụ của Phil Sandler, Mitch Wheat và Martin bên dưới, tôi cũng thấy rằng IDENTITY nhanh hơn. Nhưng đó không phải là cách chèn hàng thông thường và tôi vẫn không hiểu tại sao thử nghiệm ban đầu bị sai: ngay cả khi tôi bỏ qua GETDATE () từ ví dụ ban đầu của mình, IDENTITY () vẫn chậm hơn. Vì vậy, có vẻ như cách duy nhất để làm cho IDENTITY () vượt trội hơn NEWSEQUENTIALID () là chuẩn bị các hàng để chèn vào một bảng tạm thời và thực hiện nhiều lần chèn dưới dạng chèn hàng loạt bằng cách sử dụng bảng tạm thời này. Nói chung, tôi không nghĩ rằng chúng tôi đã tìm thấy một lời giải thích cho hiện tượng này và IDENTITY () dường như vẫn chậm hơn đối với hầu hết các cách sử dụng thực tế. Bất cứ ai có thể giải thích điều này?
INT IDENTITY
IDENTITY
không yêu cầu khóa bảng. Về mặt khái niệm tôi có thể thấy bạn có thể mong đợi nó sẽ lấy MAX (id) + 1, nhưng trong thực tế, giá trị tiếp theo được lưu trữ. Nó thực sự nên nhanh hơn việc tìm kiếm GUID tiếp theo.