Séquence - PAS DE CACHE vs CACHE 1


25

Existe-t-il une différence entre une SEQUENCEutilisation déclarée NO CACHEet une utilisation déclarée CACHE 1dans SQL Server 2012+?

Séquence # 1:

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

Séquence n ° 2:

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

Y a-t-il une différence entre les deux? Se comporteront-ils différemment lorsqu'ils seront utilisés dans un environnement SQL Server 2012+?

Réponses:


24

Il est difficile de donner une réponse définitive à cette question jusqu'à ce que vous trouviez réellement une différence. Je n'en ai trouvé aucun mais cela ne signifie pas qu'il n'y a pas de différence seulement que je n'en ai pas vu un dans les tests que j'ai faits.

Le test facile concerne les performances. Soit obtenir la prochaine valeur dans une boucle ou utiliser une table de nombres comme source pour générer plusieurs valeurs à la fois. Dans mes tests, il n'y avait aucune différence de performances entre l'utilisation d'aucun cache et un cache de 1 valeur, mais il y avait une amélioration significative des performances de l'utilisation d'un cache de 2.

Voici le code que j'ai utilisé pour tester les performances:

declare @D datetime = getdate();

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

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

Résultat:

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

Pour creuser un peu plus, j'ai utilisé les événements étendus sqlserver.metadata_persist_last_value_for_sequenceet sqlserver.lock_acquiredpour voir s'il y avait quelque chose de différent dans la façon dont les valeurs persistent dans la table système.

J'ai utilisé ce code pour tester l'absence de cache et la taille du cache de 1 et 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;

Il n'y a pas de différence de sortie pour l'utilisation sans cache et cache de 1.

Exemple de sortie:

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

Lorsque vous utilisez un cache de 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

Le SCH_Sverrouillage est effectué lorsqu'une valeur est requise. Et lorsque le cache est épuisé, il est suivi d'un IXet d'un Uverrou et enfin l'événement metadata_persist_last_value_for_sequenceest déclenché.

Il ne devrait donc pas y avoir de différence entre l'utilisation d'aucun cache et le cache 1 lorsqu'il s'agit de potentiellement perdre des valeurs lors d'un arrêt inattendu de SQL Server.

Enfin, j'ai remarqué quelque chose dans l'onglet Message de SSMS lors de la création d'une séquence avec le cache 1.

La taille du cache pour l'objet séquence 'dbo.S' a été définie sur NO CACHE.

Donc, SQL Server pense qu'il n'y a pas de différence et me le dit. Il y a cependant une différence sys.sequencesdans la colonne cache_size. Il est NULL pour aucun cache et 1 pour un cache de 1.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.