我一直在做一些测试,试图更好地理解 SQL Server 如何使用直方图来估计将匹配相等谓词以及 < 或 > 谓词的行数
鉴于我正在使用AdventureWorks2016 OLTP 数据库
如果能理解 SQL Server 对 = 和 > 谓词的估计过程:
/* update stats with fullscan first */
UPDATE STATISTICS Production.TransactionHistory WITH FULLSCAN
然后我可以看到该列的直方图TransactionHistory.Quantity
DBCC SHOW_STATISTICS (
'Production.TransactionHistory',
'Quantity')
下面的屏幕截图是我运行测试的直方图的顶端:
以下查询将估计 6 行,因为谓词中的值是 RANGE_HI_KEY,因此对该存储桶使用 EQ_ROWS:
SELECT *
FROM Production.TransactionHistory
WHERE Quantity = 2863
以下将估计 1.36 行,因为它不是 RANGE_HI_KEY,因此将 AVG_RANGE_ROWS 用于它所在的存储桶:
SELECT *
FROM Production.TransactionHistory
WHERE Quantity = 2862
以下“大于”查询将估计 130 行,这似乎是所有 RANGE_HI_KEY > 2863 的桶的 RANGE_ROWS 和 EQ_ROWS 的总和
SELECT *
FROM Production.TransactionHistory
WHERE Quantity > 2863
下面的类似查询,但该值不是直方图中的 RANGE_HI_KEY。SQL Server 再次估计为 130 并且似乎使用与上述相同的方法
SELECT *
FROM Production.TransactionHistory
WHERE Quantity > 2870
到目前为止,这一切都很有意义,所以我的测试转移到了“小于”查询
SELECT *
FROM Production.TransactionHistory
WHERE Quantity < 490
对于这个查询,SQL Server 估计有 109,579 行,但我不知道它是从哪里得到的:
所有存储桶的 RANGE_HI_KEY + RANGE_ROWS 直到 RANGE_HI_KEY 470 = 109,566 = 109,566 所以我们在某个地方还差 11 个。
SQL Server 如何使用直方图估计“小于”谓词将返回的行数
你矮 13 岁,而不是 11 岁:109,579 - 109,566 = 13。
如我的相关答案所示,一般的想法是在部分步骤中使用线性插值,假设均匀。
在你的情况下:
所以问题是当假设它们在直方图步骤中以500均匀分布时
RANGE_ROWS
,我们期望有多少这 23 个与谓词匹配:< 490
RANGE_HI_KEY
该计算得出13.00595。
假设使用排除一行的
-1
因素。使用时,假定该行与谓词匹配。<
DISTINCT_RANGE_ROW
<=
整个事情是应用您要求的范围的分数与直方图步骤覆盖的范围的修改。在不排除不匹配的值的情况下,它只是
@PR/@SR
.