顺序-NO CACHE vs CACHE 1


25

在SQL Server 2012+中,SEQUENCE声明使用NO CACHE和声明使用之间有区别CACHE 1吗?

顺序1:

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

顺序2:

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

两者之间有什么区别吗?在SQL Server 2012+环境中使用时,它们的行为会有所不同吗?

Answers:


24

在您真正找到区别之前,很难对这个问题给出明确的答案。我没有发现任何东西,但这并不意味着没有区别,只是我在所进行的测试中没有看到任何东西。

简单的测试就是性能。在循环中获取下一个值,或者使用数字表作为源来一次生成多个值。在我的测试中,不使用缓存和1值的缓存之间在性能上没有区别,但是使用2的缓存显着提高了性能。

这是我用来测试性能的代码:

declare @D datetime = getdate();

declare @I int = 0;
while @I < 9999
  select @I = next value for dbo.S;

select datediff(millisecond, @D, getdate());

结果:

Cache        Time(ms)
------------ --------
NO CACHE     1200
1            1200
2             600
1000           70  

为了更深入地了解,我使用了扩展事件,sqlserver.metadata_persist_last_value_for_sequencesqlserver.lock_acquired查看这些值在系统表中的持久化方式是否有所不同。

我使用此代码测试是否没有缓存,缓存大小分别为1和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;

不使用缓存和1的缓存在输出上没有区别。

样本输出:

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

使用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

SCH_S当需要一个值时,锁定完成。当缓存用尽时,后面跟着a IX和a U锁,最后metadata_persist_last_value_for_sequence触发了该事件。

因此,在意外关闭SQL Server时可能丢失值时,不使用缓存和不使用缓存1之间应该没有区别。

最后,在创建具有缓存1的序列时,我注意到SSMS的“消息”选项卡中的某些内容。

序列对象'dbo.S'的缓存大小已设置为NO CACHE。

因此,SQL Server认为没有区别,并告诉我。但是sys.sequences,该列中存在差异cache_size。对于无高速缓存,它为NULL;对于高速缓存为1,它为1。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.