Трудно дать однозначный ответ на этот вопрос, пока вы на самом деле не найдете разницу. Я не нашел ничего, но это не значит, что нет никакой разницы только в том, что я не видел ни одного в проведенных мною тестах.
Простой тест на производительность. Либо получить следующее значение в цикле, либо использовать таблицу чисел в качестве источника для создания нескольких значений одновременно. В моих тестах не было различий в производительности между отсутствием кэша и кэшем 1, но было значительное улучшение производительности при использовании кэша 2.
Это код, который я использовал для проверки производительности:
declare @D datetime = getdate();
declare @I int = 0;
while @I < 9999
select @I = next value for dbo.S;
select datediff(millisecond, @D, getdate());
Результат:
Cache Time(ms)
------------ --------
NO CACHE 1200
1 1200
2 600
1000 70
Чтобы копнуть немного глубже, я использовал расширенные события sqlserver.metadata_persist_last_value_for_sequence
и sqlserver.lock_acquired
посмотрел, было ли что-то другое в том, как значения сохраняются в системной таблице.
Я использовал этот код для проверки отсутствия кеша и размера кеша 1 и 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;
Нет разницы в выводе для использования без кеша и кеша 1.
Образец вывода:
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
При использовании кеша 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
SCH_S
Блокировка делается , когда требуется значение. И когда кеш исчерпан, за ним следует a IX
и a U
lock, и, наконец, событие metadata_persist_last_value_for_sequence
запускается.
Таким образом, не должно быть никакой разницы между использованием без кеша и кеша 1, когда речь идет о возможной потере значений при неожиданном завершении работы SQL Server.
Наконец, я заметил что-то на вкладке «Сообщение» в SSMS при создании последовательности с кешем 1.
Размер кэша для объекта последовательности 'dbo.S' был установлен на NO CACHE.
Итак, SQL Server думает, что нет никакой разницы, и говорит мне об этом. Однако есть разница в sys.sequences
столбце cache_size
. Это NULL для кеша нет и 1 для кеша 1.