加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

SQLServer inner join 不先执行where条件的优化

发布时间:2020-12-12 12:49:35 所属栏目:MsSql教程 来源:网络整理
导读:前端操作偶尔超时,发现一个查询很慢,格式如下: select * from a inner join b on b.id=a.bidinner join c on c.id=a.cidwhere a.way=1 and a.num='10000' a 表为深红色,返回240万行数据。执行了33秒。最终结果返回一条记录!可以看到其行数估计非常不准

前端操作偶尔超时,发现一个查询很慢,格式如下:

select * from a 
inner join b on b.id=a.bid
inner join c on c.id=a.cid
where a.way=1 and a.num='10000'



a 表为深红色,返回240万行数据。执行了33秒。最终结果返回一条记录!可以看到其行数估计非常不准。



看看该索引统计信息最后更新时间,是2014-12更新的。

更新整个表的统计信息:UPDATE STATISTICS DBO.TableName

更新之后再执行,结果还是一样,看来统计信息没有错。



可能大家会想到的,是先这样执行过滤。即时这样执行,优化引擎选择还是一样的。

select * 
from (select * from a where way=1 and num='10000')a 
inner join b on b.id=a.bid
inner join c on c.id=a.cid


再看上图,深红色的为a表,a表先和b表连接,生成大量数据,b表再键查找过滤条件。


现在的优化目标是: a表是先过滤条件(返回只有1行记录),再与b进行关联。


有3种处理方案:

1 . 强制使用嵌套(哈希、合并)连接

2. 使用左连接

3. 更改索引



测试:

1 . 强制使用嵌套(哈希、合并)连接

在测试这种方案时,是用了另一个测试环境,不过执行计划一样。

可以使用loop、hash、merge 连接。hash、merge消耗内存较多,所以使用了loop。

select * from a 
inner loop join b on b.id=a.bid
inner join c on c.id=a.cid
where a.way=1 and a.num='10000'

2. 使用左连接。因为只有一条记录,不改变查询结果,可以用。?

select * from a 
left join b on b.id=a.bid
left join c on c.id=a.cid
where a.way=1 and a.num='10000'

3. 更改索引

当前a表的索引为 ?ix_a(id,bid) , ix_a_num(num)

连接时,肯定首先连接的索引?ix_a(id,bid),该索引并未包括查询条件中的列。

可以重建新的索引如:ix_a(id,bid,num,way)



最后使用了第二种方法。前2种方法执行都3秒以下或不到一秒。第3种方法要改索引,就不必了。

执行结果如下图:深红色的a表可以先过滤条件再关联其他表了!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读