Es difícil dar una respuesta definitiva a esta pregunta hasta que realmente encuentre una diferencia. No he encontrado ninguno, pero eso no significa que no haya diferencia solo que no he visto uno en las pruebas que he realizado.
La prueba fácil es para el rendimiento. Obteniendo el siguiente valor en un bucle o usando una tabla de números como fuente para generar múltiples valores a la vez. En mis pruebas no hubo diferencias en el rendimiento entre el uso de ningún caché y un valor de caché de 1, pero hubo una mejora significativa en el rendimiento del uso de un caché de 2.
Este es el código que usé para probar el rendimiento:
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 profundizar un poco más, utilicé los eventos extendidos sqlserver.metadata_persist_last_value_for_sequence
y sqlserver.lock_acquired
para ver si había algo diferente en la forma en que los valores persisten en la tabla del sistema.
Usé este código para probar que no hay caché y el tamaño de caché de 1 y 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;
No hay diferencia en la salida para usar sin caché y caché de 1.
Salida de muestra:
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
Cuando se usa un caché 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
El SCH_S
bloqueo se realiza cuando se necesita un valor. Y cuando la memoria caché se agota, le sigue una IX
y la U
cerradura y finalmente metadata_persist_last_value_for_sequence
se dispara el evento .
Por lo tanto, no debería haber ninguna diferencia entre no usar caché y el caché 1 cuando se trata de perder valores potencialmente en un apagado inesperado de SQL Server.
Finalmente, noté algo en la pestaña Mensaje en SSMS al crear una secuencia con el caché 1.
El tamaño de caché para el objeto de secuencia 'dbo.S' se ha establecido en NO CACHE.
Entonces, SQL Server piensa que no hay diferencia y me lo dice. Sin embargo, hay una diferencia sys.sequences
en la columna cache_size
. Es NULL para ningún caché y 1 para un caché de 1.