SQL Server, çok deyimli bir tablo değerli işlevinin sonucunu önbelleğe alıyor mu?


22

Çok ifadeli bir tablo değerli işlevi, bir tablo değişkenindeki sonucunu döndürür.

Bu sonuçlar hiç tekrar kullanıldı mı, yoksa her çağrıldığında işlev her zaman tam olarak değerlendiriliyor mu?

Yanıtlar:


23

Çok deyimli tablo değerli bir işlevin (msTVF) sonuçları asla ifadeler (veya bağlantılar) arasında önbelleğe veya yeniden kullanılmaz, ancak bir msTVF sonucunun aynı ifade içinde yeniden kullanılabileceği birkaç yol vardır . Bu ölçüde, bir msTVF her çağrıldığında mutlaka doldurulmaz.

Örnek msTVF

Bu (bilerek etkin değil) msTVF, her satırda bir zaman damgası olan belirli bir tam sayı aralığı döndürür:

IF OBJECT_ID(N'dbo.IntegerRange', 'TF') IS NOT NULL
    DROP FUNCTION dbo.IntegerRange;
GO
CREATE FUNCTION dbo.IntegerRange (@From integer, @To integer)
RETURNS @T table 
(
    n integer PRIMARY KEY, 
    ts datetime DEFAULT CURRENT_TIMESTAMP
)
WITH SCHEMABINDING
AS
BEGIN
    WHILE @From <= @To
    BEGIN
        INSERT @T (n)
        VALUES (@From);

        SET @From = @From + 1;
    END;
    RETURN;
END;

Statik tablo değişkeni

İşlev çağrısının tüm parametreleri sabitse (veya çalışma zamanı sabitleri), yürütme planı tablo değişkeni sonucunu bir kez doldurur. Planın geri kalanı tablo değişkenine birçok kez erişebilir. Tablo değişkeninin statik yapısı yürütme planından tanınabilir. Örneğin:

SELECT
    IR.n,
    IR.ts 
FROM dbo.IntegerRange(1, 5) AS IR
ORDER BY
    IR.n;

Şuna benzer bir sonuç döndürür:

Basit sonuç

Yürütme planı:

Basit uygulama planı

Sıralama operatörü ilk önce tablo değişkenini dolduran Tablo Değerli Fonksiyon operatörünü çağırır (bu operatörün satır döndürmediğini unutmayın). Ardından, Sıra tablo değişkeninin içeriğini döndüren ikinci girişini çağırır (bu durumda Kümelenmiş Dizin Taraması kullanarak).

Planın 'statik' bir tablo değişkeni sonucu kullandığı hediye, bir Dizinin altındaki Tablo Değerli İşlev işlecidir - tablo değişkeninin, planın geri kalanının başlayabilmesi için bir kez önce doldurulması gerekir.

Birden çok erişim

Bir kereden fazla erişilen tablo değişkeni sonucunu göstermek için, 1'den 5'e kadar sıralanan satırlara sahip ikinci bir tablo kullanacağız:

IF OBJECT_ID(N'dbo.T', 'U') IS NOT NULL
    DROP TABLE dbo.T;

CREATE TABLE dbo.T (i integer NOT NULL);

INSERT dbo.T (i) 
VALUES (1), (2), (3), (4), (5);

Ve bu tabloyu fonksiyonumuza ekleyen yeni bir sorgu (bu eşit olarak bir yazılabilir APPLY):

SELECT T.i,
       IR.n,
       IR.ts
FROM dbo.T AS T
JOIN dbo.IntegerRange(1, 5) AS IR
    ON IR.n = T.i;

Sonuç:

Sonuca katıl

Yürütme planı:

Plana katıl

Daha önce olduğu gibi, Dizi ilk önce msTVF sonucundaki değişken değişkenini doldurur. Daha sonra, iç içe döngüler tablodaki her satıra katılmak için kullanılırT msTVF sonucundan bir satıra eklemek için kullanılır. İşlev tanımı, tablo değişkenine yardımcı bir dizin içerdiğinden, bir dizin araması kullanılabilir.

Kilit nokta, msTVF'nin parametreleri sabit olduğunda (değişkenler ve parametreler dahil) veya yürütme motoru tarafından ifade için çalışma zamanı sabitleri olarak değerlendirildiğinde, plan, msTVF tablo değişkeni sonucu için iki ayrı işleci içerecektir: tablo; sonuçlara erişmek, muhtemelen tabloya birden çok kez erişmek ve işlev tanımında beyan edilen indeksleri kullanmak için bir başka sonuç.

İlişkili parametreler ve sabit olmayan parametreler

İlişkili parametreler (dış referanslar) veya sabit olmayan fonksiyon parametreleri kullanıldığında farkları vurgulamak için, tablonun içeriğini değiştireceğiz, Tböylece fonksiyonun yapacak daha çok işi olacaktır:

TRUNCATE TABLE dbo.T;

INSERT dbo.T (i) 
VALUES (50001), (50002), (50003), (50004), (50005);

Aşağıdaki değiştirilmiş sorgu şimdi Tişlev parametrelerinden birinde tabloya bir dış başvuru kullanıyor :

SELECT T.i,
       IR.n,
       IR.ts
FROM dbo.T AS T
CROSS APPLY dbo.IntegerRange(1, T.i) AS IR
WHERE IR.n = T.i;

Bu sorgu, şöyle sonuç döndürmek için yaklaşık 8 saniye sürer :

İlişkili sonuç

Sütun içindeki satırlar arasındaki zaman farkına dikkat edin ts. WHEREMaddesi bir makul büyüklükte bir çıkış için nihai sonucu sınırlar, verimsiz fonksiyonu hala 50.000 tek sıra (dekorele değerine bağlı olarak tablo değişken doldurmak için bir süre alır itablodan T).

Yürütme planı:

İlişkili uygulama planı

Sıra operatörünün eksikliğine dikkat edin. Şimdi, tablo değişkenini dolduran ve iç içe geçmiş döngüler birleşiminin her yinelemesinde satırlarını döndüren tek bir Tablo Değerli İşlev işleci var .

Açık olması: Tablo T'deki sadece 5 satır ile Tablo Değerli İşlev işleci 5 kez çalışır. İlk yinelemede 50.001 satır, ikincisinde 50.002 satır vb. Oluşturur. Tablo değişkeni yinelemeler arasında 'atılır' (kesilir), bu nedenle beş çağrının her biri tam bir popülasyondur. Bu yüzden çok yavaştır ve her satırın sonuçta görünmesi yaklaşık aynı zaman alır.

Yan notlar:

Doğal olarak, yukarıdaki senaryo, msTVF'nin her bir yinelemede birçok satır doldurduğunda performansın ne kadar düşük olabileceğini göstermeye kasıtlı olarak düzenlenmektedir.

Bir mantıklı Yukarıdaki kod uygulaması kuracak hem üzere msTVF parametreleri ive gereksiz kaldırmak WHEREmaddesini. Tablo değişkeni hala her yinelemede kesilir ve yeniden doldurulur, ancak her seferinde yalnızca bir satır olur.

Ayrıca minimum ve maksimum ideğerleri alabilir Tve önceki adımda değişkenlerde saklayabiliriz. İlişkili parametreler yerine değişkenlerle fonksiyon çağırmak, 'statik' tablo değişken modelinin daha önce belirtildiği gibi kullanılmasını sağlar.

Değişmeyen korelasyon parametreleri için önbellekleme

Sıradaki soruyu bir kez daha ele almak için, Sıra statik modelinin kullanılamadığı durumlarda, SQL Server, iç içe geçmiş bir döngü birleşiminin önceki yinelemesinden bu yana ilişkili parametrelerden hiçbiri değişmediyse, msTVF tablo değişkenini kesmekten ve tekrar kullanmaktan kaçınabilir .

Bunu göstermek için, içeriğini Tbeş özdeş i değerle değiştireceğiz:

TRUNCATE TABLE dbo.T;

INSERT dbo.T (i) 
VALUES (50005), (50005), (50005), (50005), (50005);

Yine ilişkili bir parametre ile sorgu:

SELECT T.i,
       IR.n,
       IR.ts
FROM dbo.T AS T
CROSS APPLY dbo.IntegerRange(1, T.i) AS IR
WHERE IR.n = T.i;

Bu kez sonuçlar yaklaşık 1,5 saniye içinde belirir :

Özdeş satır sonuçları

Her satırdaki aynı zaman damgalarına dikkat edin. Tablo değişkenindeki önbelleklenmiş sonuç, ilişkili değerin ideğişmediği sonraki tekrarlamalar için tekrar kullanılır . Sonucun tekrar kullanılması her seferinde 50,005 satır eklemekten çok daha hızlıdır.

Uygulama planı öncekine çok benziyor:

Aynı satırları planlayın

Önemli fark, Tablo Değerli İşlev işlecinin Gerçek Yeniden Bağlamalar ve Gerçek Geri Sarmalar özelliklerindedir:

Operatör özellikleri

İlişkili parametreler değişmediğinde, SQL Server geçerli sonuçları tablo değişkeninde yeniden oynatabilir (geri sarabilir). Korelasyon değiştiğinde, SQL Server, tablo değişkenini kesmeli ve yeniden doldurmalıdır (yeniden bağlama). Bir isyan ilk iterasyonda olur; sonraki dört yineleme, değeri T.ideğişmediğinden geri sarar .

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.