На це питання важко дати остаточну відповідь, поки ви фактично не знайдете різниці. Я не знайшов жодного, але це не означає, що немає різниці лише в тому, що я не бачив жодного в тестах, які я робив.
Найпростіший тест на продуктивність. Або отримання наступного значення в циклі, або використання таблиці чисел як джерела для генерування кількох значень одночасно. У моїх тестах не було різниці в продуктивності між використанням кеша і кешем 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
і U
блокування, і нарешті подія metadata_persist_last_value_for_sequence
буде запущено.
Таким чином, не повинно бути різниці між використанням кеша і кеша 1, якщо мова йде про потенційно втрачені значення при несподіваному відключенні SQL Server.
Нарешті я щось помітив на вкладці Повідомлення в SSMS, коли створював послідовність із кешем 1.
Розмір кешу для об’єкта послідовності 'dbo.S' встановлено на NO CACHE.
Отже, SQL Server вважає, що немає різниці, і мені це говорить. Однак в sys.sequences
стовпці є різниця cache_size
. Це NULL для не кешу і 1 для кешу 1.