ตั้งแต่บทความ Itzik Ben Ganถูกเขียนขนาดแคช hardcoded ที่ 10 สำหรับIDENTITY
ดูเหมือนว่าจะมีการเปลี่ยนแปลง จากความคิดเห็นในรายการเชื่อมต่อนี้
ขนาดของการจัดสรรล่วงหน้าขึ้นอยู่กับขนาดของชนิดข้อมูลของคอลัมน์ที่คุณสมบัติการระบุไว้ สำหรับคอลัมน์จำนวนเต็ม SQL Server เซิร์ฟเวอร์จะจัดสรรข้อมูลประจำตัวในช่วงของค่า 1,000 ค่า สำหรับข้อมูล bigint ให้พิมพ์เซิร์ฟเวอร์จัดสรรล่วงหน้าในช่วง 10,000 ค่า
T-SQL สอบถามหนังสือมีตารางต่อไปนี้ แต่เน้นว่าค่าเหล่านี้จะไม่ได้รับเอกสารหรือรับประกันว่าจะไม่มีการเปลี่ยนแปลง
+-----------------+-----------+
| DataType | CacheSize |
+-----------------+-----------+
| TinyInt | 10 |
| SmallInt | 100 |
| Int | 1,000 |
| BigInt, Numeric | 10,000 |
+-----------------+-----------+
บทความที่นี่ทดสอบขนาดแคชลำดับและการแทรกขนาดแบตช์ต่างๆและเกิดขึ้นกับผลลัพธ์ต่อไปนี้
ซึ่งดูเหมือนจะแสดงให้เห็นว่าการแทรกขนาดใหญ่ออกมาดำเนินการIDENTITY
SEQUENCE
มันไม่ได้ทดสอบขนาดแคช 1,000 และผลลัพธ์เหล่านั้นเป็นเพียงการทดสอบเดียว มองที่ขนาดแคช 1,000 โดยเฉพาะด้วยขนาดของแบตช์ต่าง ๆ ฉันได้ผลลัพธ์ดังต่อไปนี้ (ลองแต่ละชุดขนาด 50 ครั้งและรวมผลลัพธ์เป็นด้านล่าง - ทุกครั้งในหน่วยμ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 |
+------------+-----------+-----------+-----------+-----------+-----------+-----------+
สำหรับขนาดแบทช์ที่ใหญ่กว่าIDENTITY
รุ่นดูเหมือนเร็วกว่าปกติ
หนังสือการสืบค้น TSQL ยังอธิบายว่าทำไมIDENTITY
สามารถมีข้อได้เปรียบด้านประสิทธิภาพมากกว่าลำดับ
IDENTITY
เป็นเฉพาะของตารางและSEQUENCE
ไม่ได้เป็น หากภัยพิบัติเกิดขึ้นกับการแทรกกลางก่อนที่บัฟเฟอร์การบันทึกจะถูกลบทิ้งไม่สำคัญว่าข้อมูลประจำตัวที่กู้คืนนั้นเป็นรหัสก่อนหน้านี้เนื่องจากกระบวนการกู้คืนจะยกเลิกการแทรกดังนั้น SQL Server จึงไม่บังคับให้ล้างบัฟเฟอร์บันทึกในทุก ๆ การเขียนดิสก์ที่เกี่ยวข้องกับแคช อย่างไรก็ตามสำหรับ Sequence สิ่งนี้ถูกบังคับใช้เนื่องจากค่าอาจถูกใช้เพื่อวัตถุประสงค์ใด ๆ - รวมถึงภายนอกฐานข้อมูล ดังนั้นในตัวอย่างข้างต้นที่มีตัวแทรกนับล้านและขนาดแคชเท่ากับ 1,000 นี่คือการบันทึกการลบอีกหนึ่งพัน
สคริปต์ที่จะทำซ้ำ
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;