É difícil dar uma resposta definitiva a essa pergunta até que você realmente encontre a diferença. Não encontrei nenhum, mas isso não significa que não haja diferença, apenas porque não vi nenhum nos testes que fiz.
O teste fácil é para desempenho. Obter o próximo valor em um loop ou usar uma tabela de números como fonte para gerar vários valores por vez. Nos meus testes, não houve diferença no desempenho entre o uso de nenhum cache e um cache de 1 valor, mas houve uma melhoria significativa no desempenho do uso de um cache de 2.
Este é o código que eu usei para testar o desempenho:
declare @D datetime = getdate();
declare @I int = 0;
while @I < 9999
select @I = next value for dbo.S;
select datediff(millisecond, @D, getdate());
Resultado:
Cache Time(ms)
------------ --------
NO CACHE 1200
1 1200
2 600
1000 70
Para aprofundar um pouco, usei os eventos estendidos sqlserver.metadata_persist_last_value_for_sequence
e sqlserver.lock_acquired
para ver se havia algo diferente em como os valores persistem na tabela do sistema.
Usei esse código para testar se não há cache e tamanho de cache 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;
Não há diferença na saída para não usar cache e cache 1.
Saída de amostra:
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
Ao usar um 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
O SCH_S
bloqueio é feito quando um valor é necessário. E quando o cache está esgotado, é seguido por um IX
e um U
bloqueio e, finalmente, o evento metadata_persist_last_value_for_sequence
é acionado.
Portanto, não deve haver diferença entre usar nenhum cache ee cache 1 quando se trata de potencialmente perder valores em um desligamento inesperado do SQL Server.
Finalmente, notei algo na guia Mensagem no SSMS ao criar uma sequência com o cache 1.
O tamanho do cache para o objeto de sequência 'dbo.S' foi definido como NO CACHE.
Então, o SQL Server acha que não há diferença e me diz isso. No entanto, há uma diferença na sys.sequences
coluna cache_size
. É NULL para nenhum cache e 1 para um cache de 1.