Kể từ khi bài viết Itzik Ben Gan được viết, kích thước bộ đệm được mã hóa là 10 cho IDENTITY
dường như đã được thay đổi. Từ các ý kiến về mục kết nối này
Kích thước của phân bổ trước dựa trên kích thước của kiểu dữ liệu của cột mà thuộc tính nhận dạng được xác định. Đối với cột số nguyên Máy chủ SQL, máy chủ phân bổ trước danh tính trong phạm vi 1000 giá trị. Đối với kiểu dữ liệu bigint, máy chủ phân bổ trước trong phạm vi 10000 giá trị.
Các T-SQL Truy vấn cuốn sách chứa bảng sau nhưng nhấn mạnh rằng những giá trị này không được ghi nhận hoặc bảo đảm là không thay đổi.
+-----------------+-----------+
| DataType | CacheSize |
+-----------------+-----------+
| TinyInt | 10 |
| SmallInt | 100 |
| Int | 1,000 |
| BigInt, Numeric | 10,000 |
+-----------------+-----------+
Bài viết ở đây kiểm tra các kích thước bộ đệm trình tự khác nhau và chèn kích thước lô và đưa ra các kết quả sau.
Điều này dường như cho thấy rằng đối với các chèn lớn IDENTITY
thực hiện SEQUENCE
. Tuy nhiên, nó không kiểm tra kích thước bộ đệm 1.000 và những kết quả đó chỉ là một thử nghiệm. Nhìn cụ thể vào kích thước bộ đệm 1.000 với các kích cỡ chèn khác nhau, tôi nhận được các kết quả sau (thử từng kích thước lô 50 lần và tổng hợp các kết quả như dưới đây - tất cả các lần trong μs.)
+------------+-----------+-----------+-----------+-----------+-----------+-----------+
| | Sequence | Identity |
| Batch Size | Min | Max | Avg | Min | Max | Avg |
+------------+-----------+-----------+-----------+-----------+-----------+-----------+
| 10 | 2,994 | 7,004 | 4,002 | 3,001 | 7,005 | 4,022 |
| 100 | 3,997 | 5,005 | 4,218 | 4,001 | 5,010 | 4,238 |
| 1,000 | 6,001 | 19,013 | 7,221 | 5,982 | 8,006 | 6,709 |
| 10,000 | 26,999 | 33,022 | 28,645 | 24,015 | 34,022 | 26,114 |
| 100,000 | 189,126 | 293,340 | 205,968 | 165,109 | 234,156 | 173,391 |
| 1,000,000 | 2,208,952 | 2,344,689 | 2,269,297 | 2,058,377 | 2,191,465 | 2,098,552 |
+------------+-----------+-----------+-----------+-----------+-----------+-----------+
Đối với kích thước lô lớn hơn, IDENTITY
phiên bản thường có vẻ nhanh hơn .
Cuốn sách Truy vấn TSQL cũng giải thích tại sao IDENTITY
có thể có lợi thế về hiệu suất theo trình tự.
Bảng IDENTITY
là cụ thể và SEQUENCE
không. Nếu thảm họa xảy ra với mid insert trước khi bộ đệm log bị xóa thì không có vấn đề gì nếu nhận dạng được khôi phục là trước đó vì quá trình khôi phục cũng sẽ hoàn tác chèn, vì vậy SQL Server không buộc xóa bộ đệm log trên mỗi nhận dạng bộ nhớ cache liên quan đến đĩa ghi. Tuy nhiên đối với Sequence này được thi hành vì giá trị có thể được sử dụng cho bất kỳ mục đích nào - bao gồm cả bên ngoài cơ sở dữ liệu. Vì vậy, trong ví dụ trên với một triệu lần chèn và kích thước bộ đệm là 1.000, đây là một nghìn lần xóa nhật ký.
Kịch bản để tái tạo
DECLARE @Results TABLE(
BatchCounter INT,
NumRows INT,
SequenceTime BIGINT,
IdTime BIGINT);
DECLARE @NumRows INT = 10,
@BatchCounter INT;
WHILE @NumRows <= 1000000
BEGIN
SET @BatchCounter = 0;
WHILE @BatchCounter <= 50
BEGIN
--Do inserts using Sequence
DECLARE @SequenceTimeStart DATETIME2(7) = SYSUTCDATETIME();
INSERT INTO dbo.t1_Seq1_cache_1000
(c1)
SELECT N
FROM [dbo].[TallyTable] (@NumRows)
OPTION (RECOMPILE);
DECLARE @SequenceTimeEnd DATETIME2(7) = SYSUTCDATETIME();
--Do inserts using IDENTITY
DECLARE @IdTimeStart DATETIME2(7) = SYSUTCDATETIME();
INSERT INTO dbo.t1_identity
(c1)
SELECT N
FROM [dbo].[TallyTable] (@NumRows)
OPTION (RECOMPILE);
DECLARE @IdTimeEnd DATETIME2(7) = SYSUTCDATETIME();
INSERT INTO @Results
SELECT @BatchCounter,
@NumRows,
DATEDIFF(MICROSECOND, @SequenceTimeStart, @SequenceTimeEnd) AS SequenceTime,
DATEDIFF(MICROSECOND, @IdTimeStart, @IdTimeEnd) AS IdTime;
TRUNCATE TABLE dbo.t1_identity;
TRUNCATE TABLE dbo.t1_Seq1_cache_1000;
SET @BatchCounter +=1;
END
SET @NumRows *= 10;
END
SELECT NumRows,
MIN(SequenceTime) AS MinSequenceTime,
MAX(SequenceTime) AS MaxSequenceTime,
AVG(SequenceTime) AS AvgSequenceTime,
MIN(IdTime) AS MinIdentityTime,
MAX(IdTime) AS MaxIdentityTime,
AVG(IdTime) AS AvgIdentityTime
FROM @Results
GROUP BY NumRows;