Послідовність - NO CACHE vs CACHE 1


25

Чи є різниця між SEQUENCEоголошеним використанням NO CACHEта заявленим використанням CACHE 1у SQL Server 2012+?

Послідовність №1:

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

Послідовність №2:

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

Чи є різниця між ними? Чи поводяться вони по-різному при використанні в середовищі SQL Server 2012+?

Відповіді:


24

На це питання важко дати остаточну відповідь, поки ви фактично не знайдете різниці. Я не знайшов жодного, але це не означає, що немає різниці лише в тому, що я не бачив жодного в тестах, які я робив.

Найпростіший тест на продуктивність. Або отримання наступного значення в циклі, або використання таблиці чисел як джерела для генерування кількох значень одночасно. У моїх тестах не було різниці в продуктивності між використанням кеша і кешем 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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.