目前我正试图弄清楚 SQL Server 如何评估部分覆盖直方图步骤的范围谓词的基数。
在互联网上,在cardinality-estimation-for-and-for-intra-step-statistics-value我遇到了一个类似的问题,Paul White 给出了一个相当有趣的答案。
根据Paul的回答,谓词>=和>的基数估计公式(在这种情况下,我只对至少120的基数估计器模型感兴趣)如下:
对于 >:
Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * (F * (DISTINCT_RANGE_ROWS - 1)))
Run Code Online (Sandbox Code Playgroud)
对于 >=:
Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * ((F * (DISTINCT_RANGE_ROWS - 1)) + 1))
Run Code Online (Sandbox Code Playgroud)
我基于范围谓词使用TransactionDate列和“20140614”和“20140618”之间的日期时间范围测试了这些公式在AdventureWorks2014数据库的[Production].[TransactionHistory]表上的应用。
这个范围的直方图步骤的统计如下:
根据公式,我计算了以下查询的基数:
SELECT COUNT(1)
FROM [AdventureWorks2014].[Production].[TransactionHistory]
WHERE [TransactionDate] BETWEEN '20140615 00:00:00.000' AND '20140616 00:00:00.000'
Run Code Online (Sandbox Code Playgroud)
使用以下代码进行计算:
DECLARE @predStart DATETIME = '20140615 00:00:00.000'
DECLARE @predEnd DATETIME = '20140616 00:00:00.000'
DECLARE @stepStart DATETIME = '20140614 00:00:00.000'
DECLARE @stepEnd …
Run Code Online (Sandbox Code Playgroud) sql-server query optimization sql-server-2014 cardinality-estimates
现在,我面临着基数估计的逻辑问题,这个问题在一个看似相当简单的情况下对我来说不是很清楚。我在工作中遇到过这种情况,因此出于隐私考虑,下面仅对问题进行一般性描述,但为了更详细的分析,我在AdventureWorksDW培训基地中模拟了此问题。
有以下形式的查询:
SELECT <some columns>
FROM <some dates table>
CROSS APPLY(
SELECT
<some p columns>
FROM <some table> p
WHERE p.StartDate <= Dates.d
AND p.EndDate >= Dates.d
) t
Run Code Online (Sandbox Code Playgroud)
从上面给出的执行计划中可以看出,基数估计器估计索引查找操作中的估计行数为 17,884,200(对应于 NL 外部的每行 2,980,700),这与实际数量非常接近.
现在我将修改查询并添加到 CROSS APPLY LEFT OUTER JOIN:
SELECT <some columns t>
FROM <some dates table>
CROSS APPLY(
SELECT
<some p columns>
<some columns f>
FROM <some table> p
LEFT JOIN <some table> f ON p.key = f.key
AND f.date = Dates.d
WHERE p.StartDate <= Dates.d
AND p.EndDate …
Run Code Online (Sandbox Code Playgroud) sql-server optimization cross-apply cardinality-estimates query-performance