Thật khó để đưa ra một câu trả lời dứt khoát cho câu hỏi này cho đến khi bạn thực sự tìm thấy một sự khác biệt. Tôi đã không tìm thấy nhưng điều đó không có nghĩa là không có sự khác biệt chỉ là tôi chưa thấy một trong các thử nghiệm tôi đã thực hiện.
Các bài kiểm tra dễ dàng là cho hiệu suất. Hoặc nhận giá trị tiếp theo trong một vòng lặp hoặc sử dụng bảng số làm nguồn để tạo nhiều giá trị cùng một lúc. Trong các thử nghiệm của tôi, không có sự khác biệt về hiệu suất giữa việc không sử dụng bộ đệm và bộ đệm 1 giá trị nhưng có sự cải thiện hiệu suất đáng kể khi sử dụng bộ đệm là 2.
Đây là mã tôi đã sử dụng để kiểm tra hiệu suất:
declare @D datetime = getdate();
declare @I int = 0;
while @I < 9999
select @I = next value for dbo.S;
select datediff(millisecond, @D, getdate());
Kết quả:
Cache Time(ms)
------------ --------
NO CACHE 1200
1 1200
2 600
1000 70
Để tìm hiểu sâu hơn một chút, tôi đã sử dụng các sự kiện mở rộng sqlserver.metadata_persist_last_value_for_sequence
và sqlserver.lock_acquired
để xem liệu có gì khác biệt trong cách các giá trị vẫn tồn tại trong bảng hệ thống hay không.
Tôi đã sử dụng mã này để kiểm tra không có bộ đệm và kích thước bộ đệm của 1 và 4.
DECLARE @S NVARCHAR(max) = '
CREATE EVENT SESSION SeqCache ON SERVER
ADD EVENT sqlserver.lock_acquired(
WHERE (sqlserver.session_id=({SESSIONID}))),
ADD EVENT sqlserver.metadata_persist_last_value_for_sequence(
WHERE (sqlserver.session_id=({SESSIONID})))
ADD TARGET package0.event_file(SET filename=N''d:\SeqCache'');';
SET @S = REPLACE(@S, '{SESSIONID}', CAST(@@SPID AS NVARCHAR(max)));
EXEC (@S);
GO
CREATE SEQUENCE dbo.S
AS INT
START WITH 1
INCREMENT BY 1
MINVALUE 1
MAXVALUE 9999
NO CYCLE
NO CACHE;
-- CACHE 1;
-- CACHE 4;
GO
ALTER EVENT SESSION SeqCache ON SERVER STATE = START;
GO
DECLARE @I INT = 0;
WHILE @I < 10
SELECT @I = NEXT VALUE FOR dbo.S;
GO
ALTER EVENT SESSION SeqCache ON SERVER STATE = STOP;
DROP EVENT SESSION SeqCache ON SERVER;
DROP SEQUENCE dbo.S;
Không có sự khác biệt trong đầu ra cho việc sử dụng không có bộ đệm và bộ đệm của 1.
Đầu ra mẫu:
name persisted_value mode
----------------------------------------- --------------- -----
lock_acquired NULL SCH_S
lock_acquired NULL IX
lock_acquired NULL U
metadata_persist_last_value_for_sequence 1 NULL
lock_acquired NULL SCH_S
lock_acquired NULL IX
lock_acquired NULL U
metadata_persist_last_value_for_sequence 2 NULL
lock_acquired NULL SCH_S
lock_acquired NULL IX
lock_acquired NULL U
metadata_persist_last_value_for_sequence 3 NULL
Khi sử dụng bộ đệm 4.
name persisted_value mode
----------------------------------------- --------------- -----
lock_acquired NULL SCH_S
lock_acquired NULL IX
lock_acquired NULL U
metadata_persist_last_value_for_sequence 4 NULL
lock_acquired NULL SCH_S
lock_acquired NULL SCH_S
lock_acquired NULL SCH_S
lock_acquired NULL SCH_S
lock_acquired NULL IX
lock_acquired NULL U
metadata_persist_last_value_for_sequence 8 NULL
Các SCH_S
khóa được thực hiện khi một giá trị là cần thiết. Và khi bộ nhớ cache cạn kiệt, nó được theo sau bởi IX
một U
khóa và cuối cùng là sự kiện metadata_persist_last_value_for_sequence
được kích hoạt.
Vì vậy, không có sự khác biệt giữa việc sử dụng không có bộ đệm và bộ đệm 1 khi nói đến khả năng mất giá trị khi tắt máy chủ SQL bất ngờ.
Cuối cùng tôi nhận thấy một cái gì đó trong tab Tin nhắn trong SSMS khi tạo một chuỗi với bộ đệm 1.
Kích thước bộ đệm cho đối tượng chuỗi 'dbo.S' đã được đặt thành NO CACHE.
Vì vậy, SQL Server nghĩ rằng không có sự khác biệt và nói với tôi như vậy. Tuy nhiên, có một sự khác biệt trong sys.sequences
cột cache_size
. Đó là NULL không có bộ đệm và 1 cho bộ đệm là 1.