İşlev çağrılarıyla tahmini ve gerçek sorgu planı


11

SQL Server, bir birleştirme çoğaltma sorgusu bu sorguyu var:

SELECT DISTINCT
    b.tablenick,
    b.rowguid,
    c.generation,
    sys.fn_MSgeneration_downloadonly
    (
        c.generation,
        c.tablenick
    )
FROM #belong b
LEFT OUTER JOIN dbo.MSmerge_contents c ON 
    c.tablenick = b.tablenick
    AND c.rowguid = b.rowguid;

Tahmini sorgu planı 3 sorgu hakkında bilgi içerir:

  1. Yukarıdaki sorgu
  2. Fn_MSgeneration_downloadonly işlev çağrısı
  3. Fn_MSArticle_has_downloadonly_property işlev çağrısı

Gerçek sorgu planı sadece bu bilgileri içerir:

  1. Yukarıdaki sorgu

Fonksiyonlar hakkında hiçbir şey yok. İşlev bilgileri gerçek planda neden eksik?

Bu seçenekleri denedim:

SET STATISTICS PROFILE ON
SET STATISTICS XML ON

Bu da gerçek bir plan oluşturdu, ancak Management Studio'da gerçek sorgu planı seçeneğini kullandığımla aynı bölüm 2 ve 3 eksikti.

Örneğin, işlev çağrıları hakkındaki bilgileri yakalamak için Profiler'i kullansaydım hangi olayları seçerdim?


Özellikle sorgu planları ile ilgili bir cevap bulamadım, ama ben SP: StmtStarting ve SP: StmtCompleted profilli ve fonksiyon çağrıları gösterdi.

Yanıtlar:


17

Ve fonksiyonlar hakkında hiçbir şey yok. İşlev bilgileri gerçek planda neden eksik?

Bu performans nedeniyle tasarım gereğidir.

İçeren BEGINve ENDtanımdaki işlevler, her giriş satırı için yeni bir T-SQL yığın çerçevesi oluşturur. Başka bir deyişle, işlev gövdesi her giriş satırı için ayrı ayrı yürütülür . Bu tek gerçek, T-SQL skaler ve çoklu deyim işlevleriyle ilişkili çoğu performans sorununu açıklar (satır içi tablo değerli işlevlerin BEGIN...ENDsözdizimini kullanmadığını unutmayın ).

Sorunuz bağlamında, bu SHOWPLANher satır için tam çıktı ile sonuçlanır . XML planı çıktısı oldukça ayrıntılı ve üretilmesi pahalıdır, bu nedenle her satır için tam çıktı üretmek genel anlamda kötü bir fikir olacaktır.

Misal

Kimliğine göre bir ürünün adını döndüren AdventureWorks örnek veritabanında oluşturulan aşağıdaki T-SQL skaler işlevini göz önünde bulundurun :

CREATE FUNCTION dbo.DumbNameLookup
(
    @ProductID integer
)
RETURNS dbo.Name
AS
BEGIN
    RETURN
    (
        SELECT
            p.Name
        FROM Production.Product AS p
        WHERE
            p.ProductID = @ProductID
    );
END;

İcra öncesi plan

Bir yürütme öncesi plan (SSMS'de tahmini plan), üst ifade ve iç içe işlev çağrıları için plan bilgilerini gösterir:

-- Pre-execution plan shows main query and nested function call
SET SHOWPLAN_XML ON;
GO
SELECT dbo.DumbNameLookup(1);
GO
SET SHOWPLAN_XML OFF;

SSMS çıkışı:

SSMS yürütme öncesi planı

SQL Sentry Plan Explorer'da görüntülenen aynı XML , çağrıların iç içe doğasını daha net gösterir:

PE infaz öncesi planı

Yürütme sonrası çıktı

SSMS, yürütme sonrası plan çıktısı istendiğinde yalnızca ana sorgunun ayrıntılarını gösterir:

-- Post-execution plan shows main query only
SET STATISTICS XML ON;
SELECT dbo.DumbNameLookup(1);
SET STATISTICS XML OFF;

SSMS yürütme sonrası

Aksi yapmanın performans etkisi, SQL Server Profiler'deki Showplan XML İstatistik Profili Olay Sınıfı kullanılarak, işlevi birden çok kez çağıran bir sorgu kullanılarak (giriş satırı başına bir kez) gösterilebilir:

SELECT TOP (5)
    p.ProductID,
    dbo.DumbNameLookup(p.ProductID)
FROM Production.Product AS p;

Profiler çıkışı:

İzleme çıktısı

İşlev yürütmeleri için beş, üst sorgu için bir tane yürütme sonrası plan vardır. Beş işlev planı profiler alt bölmesinde şöyle görünür:

İşlev planları

Üst sorgu planı:

Ebeveyn planı

Sorguyu TOP (5)cümle olmadan yürütmek, Ürün tablosundaki 504 satırın her biri için tam bir yürütme planıyla sonuçlanır. Muhtemelen bunun daha büyük tablolarla nasıl çabucak kontrolden çıktığını görebilirsiniz.

Tetikleyicilerin durumu tersine çevrilir. Bunlar yürütme öncesi plan bilgilerini göstermez, ancak yürütme sonrası planı içerir. Bu, tetikleyicilerin kümeye dayalı doğasını yansıtır; her biri, etkilenen tüm satırlar için bir satır yerine bir kez tetiklenir.


@PaulBeyaz, tahmini yürütme planını talep ederken tetikleme planlarının gösterilmemesinin iyi bir nedeni var mı? Bu yararlı bir eksik özellik gibi görünüyor. Bunun için bir bağlantı öğesi oluşturabilirim.
usr

@usr - Belki de seçilen gerçek önbelleğe alınan plan burada açıklandığı gibi gerçek satır sayısına bağlı olarak değişebilir? technet.microsoft.com/en-us/library/…
Martin Smith

@MartinSmith bu bir sebep olabilir. Son zamanlarda, kontrol ve fk kısıtlamalarının yürütme planları için bir bağlantı öğesi tamamlandı olarak işaretlendi, böylece aynı şeyi tetikleyicilerle yapmasını umuyordum.
usr

@usr - Buradaki mi? 3 ay? Yeni bir özellik isteği için bu bir kayıt dönüşü olmalı!
Martin Smith

@MartinSmith evet, o. 1-2 gün önce "düzeltildi". Gerçekten sorgu deposunu sorgulamak zorunda değilsiniz. SSMS'de bir düğmeyi tıklamayı umuyordum. Aslında, motorun yıllar içinde dokunulmamış bir kısmında herhangi bir değişiklik gördüğüme şaşırdım. Ama belki de yoktu.
usr
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.