Sequenza - NO CACHE vs CACHE 1


25

C'è qualche differenza tra un SEQUENCEutilizzo dichiarato NO CACHEe uno dichiarato CACHE 1in SQL Server 2012+?

Sequenza n. 1:

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

Sequenza n. 2:

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

C'è qualche differenza tra i due? Si comporteranno diversamente quando vengono utilizzati in un ambiente SQL Server 2012+?

Risposte:


24

È difficile dare una risposta definitiva su questa domanda fino a quando non trovi effettivamente la differenza. Non ne ho trovato nessuno, ma ciò non significa che non vi sia alcuna differenza solo nel fatto che non ne ho visto uno nei test che ho effettuato.

Il test semplice è per le prestazioni. Ottenere il valore successivo in un ciclo o utilizzare una tabella numerica come sorgente per generare più valori contemporaneamente. Nei miei test non ci sono state differenze nelle prestazioni tra l'utilizzo di nessuna cache e una cache di 1 valore ma c'è stato un significativo miglioramento delle prestazioni nell'uso di una cache di 2.

Questo è il codice che ho usato per testare le prestazioni:

declare @D datetime = getdate();

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

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

Risultato:

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

Per approfondire un po 'ho usato gli eventi estesi sqlserver.metadata_persist_last_value_for_sequencee sqlserver.lock_acquiredper vedere se c'era qualcosa di diverso nel modo in cui i valori persistono nella tabella di sistema.

Ho usato questo codice per verificare l'assenza di cache e dimensioni della cache di 1 e 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;

Non vi è alcuna differenza nell'output per l'utilizzo di nessuna cache e cache di 1.

Uscita campione:

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

Quando si utilizza una cache di 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

Il SCH_Sblocco viene eseguito quando è necessario un valore. E quando la cache è esaurita, è seguita da un IXe un Ublocco e infine l'evento metadata_persist_last_value_for_sequenceviene generato.

Quindi non dovrebbe esserci alcuna differenza tra l'utilizzo di nessuna cache e la cache 1 quando si tratta di perdere potenzialmente valori in caso di arresto imprevisto di SQL Server.

Alla fine ho notato qualcosa nella scheda Messaggio in SSMS durante la creazione di una sequenza con cache 1.

La dimensione della cache per l'oggetto sequenza 'dbo.S' è stata impostata su NO CACHE.

Quindi, SQL Server pensa che non ci sia differenza e me lo dice. C'è comunque una differenza nella sys.sequencescolonna cache_size. È NULL per nessuna cache e 1 per una cache di 1.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.