Sıralama - CACHE vs NO CACHE 1


25

SQL Server 2012+ ile bildirilen ile bildirilen ile SEQUENCEbildirilen arasında herhangi bir fark var mı ?NO CACHECACHE 1

Sıra 1:

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

Sıra # 2:

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

İkisi arasında bir fark var mı? Bir SQL Server 2012+ ortamında kullanıldığında farklı davranacaklar mı?

Yanıtlar:


24

Gerçekten bir fark bulana kadar bu soruya kesin bir cevap vermek zor. Hiçbirini bulamadım ama bu, yaptığım testlerde sadece bir tane görmediğim kadar fark olmadığı anlamına gelmiyor.

Kolay test performans içindir. Döngüdeki bir sonraki değeri elde etmek ya da bir kerede birden çok değer üretmek için kaynak olarak sayılar tablosu kullanmak Testlerimde, önbellek kullanmama ve 1 değerli bir önbellek kullanma arasında performans açısından fark yoktu, ancak 2 önbellek kullanımında önemli bir performans artışı vardı.

Performansı test etmek için kullandığım kod:

declare @D datetime = getdate();

declare @I int = 0;
while @I < 9999
  select @I = next value for dbo.S;

select datediff(millisecond, @D, getdate());

Sonuç:

Cache        Time(ms)
------------ --------
NO CACHE     1200
1            1200
2             600
1000           70  

Ben uzun süreli etkinlikleri kullanılan biraz daha derine kazmak için sqlserver.metadata_persist_last_value_for_sequenceve sqlserver.lock_acquiredsistem tabloya nasıl değerler devam şey farklı olmadığını görmek için.

Önbellek ve 1 ve 4 önbellek boyutunu test etmek için bu kodu kullandım.

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;

Önbellek ve önbellek 1 kullanmak için çıktıda fark yoktur.

Örnek çıktı:

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 önbellek kullanırken.

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_SBir değer gerektiğinde kilit yapılır. Ve önbellek tükendiğinde bunu a IXve Ukilidi izler ve son olarak olay metadata_persist_last_value_for_sequencetetiklenir.

Bu nedenle, SQL Server'ın beklenmedik bir şekilde kapanması durumunda potansiyel olarak değer kaybetme söz konusu olduğunda, önbellek kullanma ile önbellek 1 arasında bir fark olmamalıdır.

Sonunda, önbellek 1 ile bir dizi oluştururken SSMS'deki Mesaj sekmesinde bir şey fark ettim.

'Dbo.S' dizilim nesnesi için önbellek boyutu NO CACHE olarak ayarlandı.

Yani, SQL Server fark olmadığını düşünüyor ve bana öyle söylüyor. Ancak sys.sequencessütununda bir fark var cache_size. Önbellek yok ve NULL; 1 önbellek yok.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.