Trình tự - KHÔNG CACHE so với CACHE 1


25

Có sự khác biệt nào giữa SEQUENCEkhai báo sử dụng NO CACHEvà khai báo sử dụng CACHE 1trong SQL Server 2012+ không?

Trình tự số 1:

CREATE SEQUENCE dbo.MySeqCache1
AS INT
    START WITH 1
    INCREMENT BY 1
    MINVALUE 1
    MAXVALUE 9999
    NO CYCLE
    CACHE 1;
GO

Trình tự số 2:

CREATE SEQUENCE dbo.MySeqNoCache
AS INT
    START WITH 1
    INCREMENT BY 1
    MINVALUE 1
    MAXVALUE 9999
    NO CYCLE
    NO CACHE;
GO

Có sự khác biệt nào giữa hai người không? Họ sẽ hành xử khác nhau khi được sử dụng trong môi trường SQL Server 2012+?

Câu trả lời:


24

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_sequencesqlserver.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_Skhó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 IXmột Ukhó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.sequencescột cache_size. Đó là NULL không có bộ đệm và 1 cho bộ đệm là 1.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.