Sequenz - NO CACHE vs CACHE 1


25

Gibt es einen Unterschied zwischen einer SEQUENCEdeklarierten Verwendung NO CACHEund einer deklarierten Verwendung CACHE 1in SQL Server 2012+?

Sequenz Nr. 1:

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

Sequenz Nr. 2:

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

Gibt es einen Unterschied zwischen den beiden? Verhalten sie sich in einer SQL Server 2012+ -Umgebung anders?

Antworten:


24

Es ist schwierig, eine endgültige Antwort auf diese Frage zu geben, bis Sie tatsächlich einen Unterschied feststellen. Ich habe keine gefunden, aber das bedeutet nicht, dass es keinen Unterschied gibt, nur dass ich in den Tests, die ich gemacht habe, keinen gesehen habe.

Der einfache Test ist für die Leistung. Entweder den nächsten Wert in einer Schleife abrufen oder eine Zahlentabelle als Quelle verwenden, um mehrere Werte gleichzeitig zu generieren. In meinen Tests gab es keinen Unterschied in der Leistung zwischen der Verwendung von keinem Cache und einem Cache von 1 Wert, aber es gab eine signifikante Leistungsverbesserung bei der Verwendung eines Cache von 2.

Dies ist der Code, mit dem ich die Leistung getestet habe:

declare @D datetime = getdate();

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

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

Ergebnis:

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

Um ein bisschen tiefer zu gehen, habe ich die erweiterten Ereignisse verwendet sqlserver.metadata_persist_last_value_for_sequenceund sqlserver.lock_acquiredüberprüft, ob die Werte in der Systemtabelle anders bleiben.

Ich habe diesen Code verwendet, um zu testen, ob kein Cache vorhanden ist und ob die Cachegröße 1 und 4 beträgt.

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;

Es gibt keinen Unterschied in der Ausgabe, wenn kein Cache und Cache von 1 verwendet wird.

Beispielausgabe:

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

Bei Verwendung eines Cache von 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

Die SCH_SSperre wird durchgeführt, wenn ein Wert benötigt wird. Und wenn der Cache erschöpft ist, folgt ein IXund das a- USchloss und schließlich wird das Ereignis metadata_persist_last_value_for_sequenceausgelöst.

Es sollte also keinen Unterschied zwischen der Verwendung von "no cache" und "cache 1" geben, wenn beim unerwarteten Herunterfahren von SQL Server möglicherweise Werte verloren gehen.

Schließlich habe ich etwas auf der Registerkarte Nachricht in SSMS bemerkt, als ich eine Sequenz mit Cache 1 erstellt habe.

Die Cachegröße für das Sequenzobjekt 'dbo.S' wurde auf NO CACHE gesetzt.

SQL Server ist der Meinung, dass es keinen Unterschied gibt, und teilt mir dies mit. Es gibt jedoch einen Unterschied sys.sequencesin der Spalte cache_size. Es ist NULL für keinen Cache und 1 für einen Cache von 1.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.