Sejak artikel Itzik Ben Gan ditulis, ukuran cache 10 hardcoded IDENTITY
tampaknya telah diubah. Dari komentar di item hubungkan ini
Ukuran pra-alokasi didasarkan pada ukuran tipe data dari kolom properti identitas didefinisikan. Untuk kolom integer SQL Server, server pra-mengalokasikan identitas dalam rentang 1000 nilai. Untuk tipe data bigint, server mengalokasikan sebelumnya dalam rentang nilai 10.000.
Buku T-SQL Querying berisi tabel berikut tetapi menekankan bahwa nilai-nilai ini tidak didokumentasikan atau dijamin tidak berubah.
+-----------------+-----------+
| DataType | CacheSize |
+-----------------+-----------+
| TinyInt | 10 |
| SmallInt | 100 |
| Int | 1,000 |
| BigInt, Numeric | 10,000 |
+-----------------+-----------+
Artikel di sini menguji berbagai ukuran cache urutan dan memasukkan ukuran kumpulan dan muncul dengan hasil berikut.
Yang tampaknya menunjukkan bahwa untuk sisipan besar IDENTITY
berkinerja SEQUENCE
. Namun ia tidak menguji ukuran cache 1.000 dan juga hasil tersebut hanya satu tes. Melihat secara khusus pada ukuran cache 1.000 dengan berbagai ukuran bets sisipan, saya mendapatkan hasil berikut (mencoba setiap ukuran bets 50 kali dan menggabungkan hasilnya sebagai di bawah ini - semua kali dalam μ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 |
+------------+-----------+-----------+-----------+-----------+-----------+-----------+
Untuk ukuran batch yang lebih besar, IDENTITY
versi umumnya lebih cepat .
Buku Kueri TSQL juga menjelaskan mengapa IDENTITY
bisa memiliki keunggulan kinerja dibandingkan urutan.
Ini IDENTITY
adalah tabel khusus dan SEQUENCE
tidak. Jika bencana terjadi pada pertengahan sisipan sebelum log buffer disiram, tidak masalah jika identitas yang dipulihkan adalah yang sebelumnya karena proses pemulihan juga akan membatalkan sisipan, sehingga SQL Server tidak memaksa pembilasan log buffer pada setiap identitas cache terkait menulis disk. Namun untuk urutan ini adalah ditegakkan sebagai nilai dapat digunakan untuk tujuan apapun - termasuk di luar database. Jadi, dalam contoh di atas dengan sejuta sisipan dan ukuran cache 1.000 ini adalah tambahan ribu log flushes.
Skrip untuk direproduksi
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;