Indeks Mencari Biaya Operator

9

Untuk kueri basis data sampel AdventureWorks di bawah:

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;

Rencana pelaksanaan menunjukkan Perkiraan Biaya Operator sebesar 0,0850383 (93%) untuk Pencarian Indeks :

rencana

Biaya tidak tergantung dari model estimasi kardinalitas yang digunakan.

Ini bukan penambahan sederhana dari Biaya CPU Perkiraan dan Perkiraan I / O Biaya . Biaya untuk satu pelaksanaan Indeks Seek juga tidak dikalikan dengan Estimasi Jumlah Eksekusi .

Bagaimana angka biaya ini sampai?

Paul White 9
sumber

Jawaban:

10

Logika derivasi biaya penuh adalah kompleks, tetapi untuk kasus yang relatif sederhana dalam pertanyaan:

Input

  1. Jumlah berapa kali operator dieksekusi
    Ini adalah Estimasi Jumlah Eksekusi : 504

  2. Kardinalitas (jumlah baris) dalam indeks
    yang TableCardinality milik Indeks Seek Operator memberikan ini: 113.443

  3. Jumlah halaman data dalam indeks: 201
    Nomor ini dapat diperoleh beberapa cara, misalnya dari 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. Kepadatan (1 / nilai yang berbeda ) dari indeks: 0,002267574
    Ini tersedia dalam vektor kepadatan statistik indeks:

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

    massa jenis

Komputasi

-- 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 <> biola

Hasil

Paul White 9
sumber
Kerja bagus, senang mengetahui dari mana perkiraan biaya berasal, variabel mana yang memengaruhinya dan dalam proporsi mana. Apakah ini mekanik untuk semua versi SQL Server? Mungkin beberapa perubahan konstanta?
EzLo
2
Aspek penetapan biaya ini tidak berubah sejak 2005 sejauh yang saya ketahui.
Paul White 9