Index Operate Operator Cost

9

Pour l' exemple de requête de base de données AdventureWorks ci-dessous:

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;

Le plan d'exécution indique un coût de fonctionnement estimé à 0,0850383 (93%) pour la recherche d'index :

plan

Le coût est indépendant du modèle d'estimation de cardinalité utilisé.

Il n'est pas une simple addition du coût CPU estimée et le coût d' E / S estimée . Ce n'est pas non plus le coût d'une exécution de la recherche d'index multiplié par le nombre estimatif d'exécutions .

Comment ce numéro de coût est-il obtenu?

Paul White 9
la source

Réponses:

10

La logique de dérivation des coûts complets est complexe, mais pour le cas relativement simple de la question:

Contributions

  1. Le nombre d'exécutions de l'opérateur
    Il s'agit du nombre estimé d'exécutions : 504

  2. La cardinalité (nombre total de lignes) dans l'index
    La propriété TableCardinality de l' opérateur Index Seek donne ceci: 113,443

  3. Le nombre de pages de données dans l'index: 201
    Ce nombre peut être obtenu de plusieurs façons, par exemple à partir de 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. La densité (1 / valeurs distinctes ) de l'indice: 0,002267574
    Elle est disponible dans le vecteur de densité des statistiques de l'indice:

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

    densité

Calcul

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

Résultat

Paul White 9
la source
Excellent travail, il est bon de savoir d'où vient le coût estimé, quelles variables l'affectent et dans quelle proportion. Est-ce le mécanisme pour toutes les versions de SQL Server? Peut-être quelques changements dans les constantes?
EzLo
2
À ma connaissance, cet aspect des coûts n'a pas changé depuis 2005.
Paul White 9