Sql 统计和基数估计-为什么我看到这个结果?
当我试图解决一个更复杂的问题时,我遇到了这个小问题,并且在试图找出优化器时,我已经穷途末路了。假设我有一个名为“MyTable”的表,可以这样定义:Sql 统计和基数估计-为什么我看到这个结果?,sql,sql-server,sql-server-2008,query-optimization,Sql,Sql Server,Sql Server 2008,Query Optimization,当我试图解决一个更复杂的问题时,我遇到了这个小问题,并且在试图找出优化器时,我已经穷途末路了。假设我有一个名为“MyTable”的表,可以这样定义: CREATE TABLE MyTable ( GroupClosuresID int identity(1,1) not null, SiteID int not null, DeleteDateTime datetime null , CONSTRAINT PK_MyTable PRIMARY KEY (GroupClosuresID, Si
CREATE TABLE MyTable (
GroupClosuresID int identity(1,1) not null,
SiteID int not null,
DeleteDateTime datetime null
, CONSTRAINT PK_MyTable PRIMARY KEY (GroupClosuresID, SiteID))
此表中有286685行,运行DBCC SHOW\u STATISTICS('MyTable','PK\u MyTable')
将产生:
Name Updated Rows Rows Sampled Steps Density Average key length String Index Filter Expression Unfiltered Rows
-------------------------------------------------------------------------------------------------------------------------------- -------------------- -------------------- -------------------- ------ ------------- ------------------ ------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------
PK_MyTable Aug 10 2011 1:00PM 286685 286685 18 0.931986 8 NO NULL 286685
(1 row(s) affected)
All density Average Length Columns
------------- -------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3.743145E-06 4 GroupClosuresID
3.488149E-06 8 GroupClosuresID, SiteID
(2 row(s) affected)
RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
------------ ------------- ------------- -------------------- --------------
1 0 8 0 1
129 1002 7 127 7.889764
242 826 6 112 7.375
531 2010 6 288 6.979167
717 1108 5 185 5.989189
889 822 4 171 4.807017
1401 2044 4 511 4
1763 1101 3 361 3.049861
14207 24780 1 12443 1.991481
81759 67071 1 67071 1
114457 31743 1 31743 1
117209 2047 1 2047 1
179109 61439 1 61439 1
181169 1535 1 1535 1
229410 47615 1 47615 1
235846 2047 1 2047 1
275456 39442 1 39442 1
275457 0 1 0 1
现在我在这个表上运行一个查询,没有创建额外的索引或统计信息
SELECT GroupClosuresID FROM MyTable WHERE SiteID = 1397 AND DeleteDateTime IS NULL
现在出现了两个新的统计对象,一个用于SiteID
列,另一个用于DeleteDateTime
列。分别如下(注:部分非相关信息已排除):
为上面运行的查询生成的执行计划没有让我感到意外。它包括一个简单的聚集索引扫描,估计行数为14282.3,实际行数为15676。根据我对统计和成本估算的了解,使用上述两个直方图,我们可以将SiteID的选择性(16005.02/286685)乘以DeleteDateTime的选择性(255827/286685),得到0.049818730748019的复合选择性。乘以总行数(286685)得到的结果与优化器所做的完全相同:14282.3
但这就是我感到困惑的地方。我使用create index IX_MyTable ON MyTable(SiteID,DeleteDateTime)
创建了一个索引,它创建了自己的统计对象:
Name Updated Rows Rows Sampled Steps Density Average key length String Index Filter Expression Unfiltered Rows
-------------------------------------------------------------------------------------------------------------------------------- -------------------- -------------------- -------------------- ------ ------------- ------------------ ------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------
IX_MyTable Aug 10 2011 1:41PM 286685 286685 200 0.02749305 8.822645 NO NULL
286685
(1 row(s) affected)
All density Average Length Columns
------------- -------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0.0007107321 4 SiteID
7.42611E-05 4.822645 SiteID, DeleteDateTime
3.488149E-06 8.822645 SiteID, DeleteDateTime, GroupClosuresID
(3 row(s) affected)
RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
------------ ------------- ------------- -------------------- --------------
.
.
.
1397 504 15686 12 42
.
.
.
当我运行与以前相同的查询时(从MyTable中选择GroupClosuresID,其中SiteID=1397,DeleteDateTime为NULL
),仍然返回15676行,但我估计的行数现在是181.82
我试着操纵数字,试图找出这个估计是从哪里来的,但我就是搞不懂。我必须假设它与IX_MyTable的密度值有关
任何帮助都将不胜感激。谢谢
编辑:这是最后一次查询执行的执行计划。
这一次需要挖掘 这是一个产品:
日期字段中的密度(从您的第一组统计数据NULL
255827/286685=.892363
- …乘以新索引中第一个字段(
)的密度:siteid
0.0007107321
.00071017321 * 286685 = 203.7562
-- est. rows with your value in siteid based on even distribution of values
255827 / 286685 = 0.892363
-- Probability of a NULL across all rows
203.7562 * 0.892363 = 181.8245
我猜,因为这个实例中的行数实际上不会影响任何东西,所以优化器采用了最简单的方法,将概率相乘。只是想写一下,但JNK是第一个 基本上,散列函数现在计算两列的结果。SiteID=1397和DeleteDateTime的散列函数结果为空,匹配大约181行
行估计值为181.82的运算符上执行了多少次?另外,请显示新索引的附加节点值。1执行。我还添加了一个屏幕截图。当你说附加节点值时,你指的是其他直方图值?如果我不得不猜测它与索引中的第二个键。有多少个值,你知道吗?你,先生,是一位学者和绅士。谢谢!顺便问一下,你是怎么知道的?在我看来,优化器仍然能够利用15686的值,但我想没有。我把它放进电子表格,把我们知道的所有数据放进去,然后玩一旦我找到了答案,这很有意义,但基本上我只是将行数乘以密度和频率
.00071017321 * 286685 = 203.7562
-- est. rows with your value in siteid based on even distribution of values
255827 / 286685 = 0.892363
-- Probability of a NULL across all rows
203.7562 * 0.892363 = 181.8245