Endeks Arama Operatör Maliyeti


9

İçin AdventureWorks örnek veritabanı sorgusu aşağıda:

SELECT 
    P.ProductID, 
    CA.TransactionID
FROM Production.Product AS P
CROSS APPLY
(
    SELECT TOP (1)
        TH.TransactionID
    FROM Production.TransactionHistory AS TH
    WHERE
        TH.ProductID = P.ProductID
    ORDER BY 
        TH.TransactionID DESC
) AS CA;

Yürütme planı gösterileri bir Tahmini Operatör Maliyeti ait 0.0850383 için (93%) Index Seek :

plan

Maliyet, kullanılan kardinalite tahmin modelinden bağımsızdır.

Tahmini CPU Maliyeti ve Tahmini I / O Maliyeti basit bir eklentisi değildir . Endeks Arama'nın tek bir yürütme maliyeti de Tahmini Yürütme Sayısı ile çarpılmaz .

Bu maliyet numarasına nasıl ulaşıldı?

Yanıtlar:


10

Tam maliyet türevi mantığı karmaşıktır, ancak sorudaki nispeten basit durum için:

Girdiler

  1. Operatörün yürütme sayısı
    Bu, Tahmini Yürütme Sayısı : 504

  2. Endeks içinde kardinalite (satır sayısı) TableCardinality özelliğine Index Seek operatörü bu verir: 113443

  3. Endeksteki veri sayfası sayısı: 201
    Bu sayı birden fazla yolla elde edilebilir, örneğin sys.allocation_units:

    SELECT 
        AU.data_pages
    FROM sys.allocation_units AS AU
    JOIN sys.partitions AS P
        ON P.hobt_id = AU.container_id
    WHERE
        AU.[type_desc] = N'IN_ROW_DATA'
        AND P.[object_id] = OBJECT_ID(N'Production.TransactionHistory', N'U')
        AND P.index_id = 
            INDEXPROPERTY(P.[object_id], N'IX_TransactionHistory_ProductID', 'IndexID');
    
  4. Endeksin yoğunluğu (1 / farklı değerler ): 0.002267574
    Bu, indeks istatistiklerinin yoğunluk vektöründe bulunur:

    DBCC SHOW_STATISTICS 
    (
        N'Production.TransactionHistory', 
        N'IX_TransactionHistory_ProductID'
    ) 
    WITH DENSITY_VECTOR;
    

    yoğunluk

Hesaplama

-- Input numbers
DECLARE
    @Executions float = 504,
    @Density float = 0.002267574,
    @IndexDataPages float = 201,
    @Cardinality float = 113443;

-- SQL Server cost model constants
DECLARE
    @SeqIO float = 0.000740740740741,
    @RandomIO float = 0.003125,
    @CPUbase float = 0.000157,
    @CPUrow float = 0.0000011;

-- Computation
DECLARE
    @IndexPages float = CEILING(@IndexDataPages * @Density),
    @Rows float = @Cardinality * @Density,
    @Rebinds float = @Executions - 1e0;

DECLARE
    @CPU float = @CPUbase + (@Rows * @CPUrow),
    @IO float = @RandomIO + (@SeqIO * (@IndexPages - 1e0)),
    -- sample with replacement
    @PSWR float = @IndexDataPages * (1e0 - POWER(1e0 - (1e0 / @IndexDataPages), @Rebinds));

-- Cost components (no rewinds)
DECLARE
    @InitialCost float = @RandomIO + @CPUbase + @CPUrow,
    @RebindCPU float = @Rebinds * (1e0 * @CPUbase + @CPUrow),
    @RebindIO float = (1e0 / @Rows) * ((@PSWR - 1e0) * @IO);

-- Result
SELECT 
    OpCost = @InitialCost + @RebindCPU + @RebindIO;

db <> keman

Sonuç


Harika bir iş, tahmini maliyetin nereden geldiğini, hangi değişkenlerin onu ve hangi oranda etkilediğini bilmek güzel. Bu tüm SQL Server sürümleri için tamirci mi? Sabitlerde birkaç değişiklik olabilir mi?
EzLo

2
Maliyetlendirmenin bu yönü, bildiğim kadarıyla 2005'ten bu yana değişmedi.
Paul White 9
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.