索引寻求对where

时间:2017-02-20 11:51:40

标签: sql sql-server

我有一个表ORDER有64列,OrderNo是主键。它还有两列ParentOrderNoType。对于单个订单,类型和ParentOrderNo将为NULL,对于分组订单,Type将填充“PRNT”或“CHLD”。对于其组中的所有订单(PRNT和CHLD),OrderNo where Type='PRNT'将填充到ParentOrderNo列。一组可以有1个父级和2个或更多子命令。该表具有列ParentOrderNoType的非聚集索引(IX_ORDER_1)。

此表中共有31654行。在我的测试用例中,有30001个订单(1个父级和30000个孩子)。

执行查询时:

Select top 1 *
  From   ORDER                  
  where PARENTORDERNO = '11278'  and Type ='prnt'

执行计划使用(IX_ORDER_1)

显示Index Seek

但是当我执行查询时:

Select top 1 *
  From   ORDER                  
  where PARENTORDERNO = '11278'  and Type ='chld'

执行计划显示使用聚集索引的索引扫描

有人可以指导我在执行计划中导致此更改的原因。 提前致谢

2 个答案:

答案 0 :(得分:1)

根据数据库维护的有关索引的统计信息,优化程序(正确地)估计在type='parent'时匹配条件的记录非常少,因此搜索更有效。对于type='child',它估计有足够的记录表明扫描效率更高,因为它将返回表格中的大部分内容,而不是仅返回一条记录。

在执行计划中,请查看Estimated Rows(和Actual Rows,以了解估算的准确程度)。

答案 1 :(得分:0)

不幸的是我无法添加评论,所以我这样回答:

什么时候从表中选择更多cca 15%行(百分比因来源而异,但通常它们坚持10%到15%),执行计划很可能会使用Index Scan而不是index Seek。 / p>

在你的情况下,如果我理解正确,你有

"在我的测试用例中有30001个订单(1个父级和30000个孩子)。 "

只有一个父行,它是索引搜索的良好候选者,以及30 000个子行,这对于查询优化器肯定是不好的候选者。