Pau*_*ite 10 sql-server execution-plan database-internals
对于下面的AdventureWorks示例数据库查询:
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;
Run Code Online (Sandbox Code Playgroud)
执行计划显示索引搜索的估计操作员成本为0.0850383 (93%) :
成本与使用的基数估计模型无关。
它不是简单地将Estimated CPU Cost和Estimated I/O Cost相加。它也不是指数搜索的一次执行成本乘以估计执行次数。
这个成本数字是如何得出的?
Pau*_*ite 12
完整的成本推导逻辑很复杂,但对于问题中相对简单的情况:
操作符被执行的次数
这是估计的执行次数:504
索引中的基数(总行数)Index Seek运算符
的TableCardinality属性给出:113,443
索引中的数据页数:201
这个数可以通过多种方式获得,例如从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');
Run Code Online (Sandbox Code Playgroud)索引的密度(1 /不同值):0.002267574
这在索引统计的密度向量中可用:
DBCC SHOW_STATISTICS
(
N'Production.TransactionHistory',
N'IX_TransactionHistory_ProductID'
)
WITH DENSITY_VECTOR;
Run Code Online (Sandbox Code Playgroud)
-- 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;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
608 次 |
| 最近记录: |