我有一个表ORDER
有64列,OrderNo
是主键。它还有两列ParentOrderNo
和Type
。对于单个订单,类型和ParentOrderNo
将为NULL,对于分组订单,Type
将填充“PRNT”或“CHLD”。对于其组中的所有订单(PRNT和CHLD),OrderNo where Type='PRNT'
将填充到ParentOrderNo
列。一组可以有1个父级和2个或更多子命令。该表具有列ParentOrderNo
和Type
的非聚集索引(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'
执行计划显示使用聚集索引的索引扫描
有人可以指导我在执行计划中导致此更改的原因。 提前致谢
答案 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个子行,这对于查询优化器肯定是不好的候选者。