日期:2014-05-17  浏览次数:20396 次

大牛们,加了一个or,为什么执行计划由哈希匹配变成嵌套循环?
1,语句1
select count(*) from t1 where a1='1' and a2 in(select a2 from t2)

2,语句2
select count(*) from t1 where a1='1' and (a2 in(select a2 from t2) or a2='2')

语句1的执行计划:

语句2的执行计划


表t1超过100万条数据,语句1执行时间为1秒,语句2超过80秒,请问为什么,语句2该怎样修改?

------解决方案--------------------
try this,

select count(*)
 from t1 
 where a1='1' 
 and a2 in(select a2 from t2 
           union all
           select '2' 'a2')

------解决方案--------------------
引用:
1,语句1
select count(*) from t1 where a1='1' and a2 in(select a2 from t2)

2,语句2
select count(*) from t1 where a1='1' and (a2 in(select a2 from t2) or a2='2')

语句1的执行计划:

语句2的执行计划


表t1超过100万条数据,语句1执行时间为1秒,语句2超过80秒,请问为什么,语句2该怎样修改?


建议把查询改写成关联的,inner join或者是left join,

其实要想明白,为什么加了a2='2'后,执行计划变化了,这个很难,因为这个是由SQL Server的优化器决定的,我们很难猜测优化器在一堆的判断当中为什么选了nested loop 而不选hash join,

但如果你写成inner join或者left join的时候,如果速度不佳,你可以通过添加查询提示,比如hash:

inner hash join

其实本质上就是手动给SQL Server的优化器建议,建议他采用hash join,之所以微软会提供这种查询提示,就是已经预料到会有你所遇到的问题,所以才提供了这种可以由你来进行微调的技术。