性能优化实战-join与where条件执行顺序
昨天经历了一场非常痛苦的性能调优过程,但是收获也是刻骨铭心的,感觉对sql引擎的原理有了进一步认识。
问题起源于测试人员测一个多条件检索的性能时,发现按某个条件查询会特别慢。对应的sql语句简化为:
- select * from ta a,tb b
- where a.bid=b.id
- and a.col1='xx'
- and b.col2='yy'
- and dbo.func(a.col3,'zz')=1
ta表几万行,tb几百行。
大家看到了,慢的那个条件就是"and dbo.func(a.col3,'zz')=1". 这里用到自定义函数是迫不得已的,原因暂且不表。所以当qa只用a.col3查的时候,需要遍历ta表,对每一行应用函数,不慢才怪 呢。由于a.col3不是主要条件,qa就不跟我纠结这个问题了。但是qa又用b.col2和a.col3一起查询,最终结果才几十条,为什么还是非常慢。我说sql估计还是先全表执行了那个函数,所以还是慢。qa说无法接受,然后提了个bug。
其实我也非常纳闷,为啥sql引擎会制定出那么sx的执行计划,明明先用b.col2过滤,再做表连接,再去用函数过滤,该多好?!没办法,我只好耐下心来,研究执行计划。
看了计划发现,ta条件和tb的条件是并行过滤的,过滤完之后再做连接。我开始考虑,能不能做点什么,让sql按想要的步骤来走。于是:
1. 在a.col1上加了索引,发现没啥提升,原来a.col1='xx'并没有过滤掉多少数据。
2. 在b.col2上加了索引,也没提升,依然是函数执行完毕后才连接。
3. 在a.col3上建索引?a.col3是个复杂文本,建索引没有任何意义。
4. 把写法改为join,并且把各个条件在on和where之间来回倒腾,没用。
5. 想把函数加个with schemabinding, 但放弃了,这个函数的性能其实已经到极限了,指定架构的话,怕是没什么提升,而且又加了额外的限制,不妥。
6. 想加一个undocument的查询提示,不让它并行过滤。既然select末尾加上OPTION (QUERYTRACEON 8649)可以强制并行,那我把8649换成其他数字能强制不走并行吗?换了好几个,都没用。后来才发现,这个querytraceon的并行和本文的并行没有半毛钱关系。
7. 使用嵌套查询。加一层select * from,把func条件提到外层来。按道理,func应该最后过滤了吧!结果,还是一样的执行计划。我是该夸sql engine太智能呢,还是该骂它太sb呢?
8. 准备在代码里动手脚,结果代码冻结了……只准改sql。
manager说今天必须搞定,不然影响今天发包。
黔驴技穷。四面楚歌。
无计可施了,我只能做点边边角角的事情,想把整体性能再弄好一点,比如,许多重要的索引在当前的新库上都没建好,于是我就一个个补上去,其中包括a.bid上的索引。这时候,奇迹发生了,那个很慢的查询突然变得飞快!!!在那一刻,我顿悟了,为什么之前一直是最后才进行表连接?因为sql engine啃不动func这个东西,连接条件上又没有索引,所以只好按常规套路,先执行各表的过滤条件,尽量让待连接的行数减到最小,最后再做关联。
至此,问题解决:)
总结一下:
1. 关联字段上的索引非常重要。
2. 把条件放在(inner)join-on或者where后面,以及条件的先后顺序,对效率影响不大(仅针对Sqlserver)。但我个人习惯是,两表连接条件放在join-on后面,各表自己的过滤条件放在where后面,尊重语义,易读易维护。
性能优化实战-join与where条件执行顺序的更多相关文章
- 优化 : Oracle数据库Where条件执行顺序 及Where子句的条件顺序对性能的影响
.Oracle数据库Where条件执行顺序: 由于SQL优化起来比较复杂,并且还会受环境限制,在开发过程中,写SQL必须必须要遵循以下几点的原则: 1.ORACLE采用自下而上的顺序解析WHERE子句 ...
- Golang 性能优化实战
小结: 1. 性能查看工具 pprof,trace 及压测工具 wrk 或其他压测工具的使用要比较了解. 代码逻辑层面的走读非常重要,要尽量避免无效逻辑. 对于 golang 自身库存在缺陷的,可以寻 ...
- 网站性能优化实战——从12.67s到1.06s的故事
文章摘自https://juejin.im/post/5b0b7d74518825158e173a0c 作为互联网项目,最重要的便是用户体验.在举国“互联网+”的热潮中,用户至上也已经被大多数企业所接 ...
- 小程序Canvas性能优化实战
以下内容转载自totoro的文章<小程序Canvas性能优化实战!> 作者:totoro 链接:https://blog.totoroxiao.com/canvas-perf-mini/ ...
- 我把阿里、腾讯、字节跳动、美团等Android性能优化实战整合成了一个PDF文档
安卓开发大军浩浩荡荡,经过近十年的发展,Android技术优化日异月新,如今Android 11.0 已经发布,Android系统性能也已经非常流畅,可以在体验上完全媲美iOS. 但是,到了各大厂商手 ...
- 什么时候出现死锁,如何解决?mysql 引擎? 多个like or 查询sql如何优化?什么是常量池?for条件执行顺序
1. 什么时候出现死锁,如何解决?mysql 引擎? 多个like or 查询sql如何优化? 资源竞争导致死锁,比如A B 同时操作两条记录,并等待对方释放锁. 优化sql, 加缓存,主从(如读写分 ...
- ORACLE中查询语句的执行顺及where部分条件执行顺序测试
Oracle中的一些查询语句及其执行顺序 原文地址:https://www.cnblogs.com/likeju/p/5039115.html 查询条件: 1)LIKE:模糊查询,需要借助两个通配符, ...
- 从join on和where执行顺序认识T-SQL查询处理执行顺序
先从一例子看join on 和 where执行结果的不同 CREATE TABLE "SCOTT"."A" ( "PERSON_ID" ) ...
- MySQL查询语句执行过程及性能优化(JOIN/ORDER BY)-图
http://blog.csdn.net/iefreer/article/details/12622097 MySQL查询语句执行过程及性能优化-查询过程及优化方法(JOIN/ORDER BY) 标签 ...
随机推荐
- ubuntu 搭建Mercurial 服务(nginx)
ubuntu 搭建Mercurial 服务(nginx) 环境:ubuntu 12.05 Mercurial 步骤: (1)安装nginx 和 Mercurial: sudo apt-get ins ...
- (转) shiro权限框架详解06-shiro与web项目整合(上)
http://blog.csdn.net/facekbook/article/details/54947730 shiro和web项目整合,实现类似真实项目的应用 本文中使用的项目架构是springM ...
- 记一次IOS对 JS的支持问题
最终在这位博主那块找到问题https://blog.csdn.net/github_36487770/article/details/82465741 在利用Vue开发一个功能时遇到时间拼接格式化问题 ...
- 什么时候用created,什么时候用mounted
created 在实例创建完成后被立即调用.在这一步,实例已完成以下的配置:数据观测 (data observer), 属性和方法的运算,watch/event 事件回调.然而,挂载阶段还没开始,$e ...
- C#学习 第九节
构造器 1.构造器(constructor)是类型的成员之一: 2.狭义的构造器是指“实例构造器”(instance constructor): 3.构造器的调用 student stu =new s ...
- SQL中group by的理解
1.group by A,B,C的分组顺序与汇总: group by A,B,C的分组顺序与order by A,B,C的排序一样.即先按A,如果A一样,则再按B,以此类推. 而数据将在最后指定的分组 ...
- C++基础 (4) 第四天 this指针 全局函数和成员函数 友元 操作符重载
1static强化练习-仓库进货和出货 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; c ...
- reMarkable安装教程
PS :每次都下一遍安装包挺无奈的...... 系统版本 :Ubuntu 16.04 安装包 :remarkable_1.87_all.deb 链接 Here!-> reMarkable 安装步 ...
- [USACO17JAN] Promotion Counting晋升者计数 (树状数组+dfs)
题目大意:给你一棵树,求以某节点为根的子树中,权值大于该节点权值的节点数 本题考查dfs的性质 离散+树状数组求逆序对 先离散 我们发现,求逆序对时,某节点的兄弟节点会干扰答案 所以,我们在递推时统计 ...
- Profile 动态切换环境
一.多 Profile 文件我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml默认使用 application.properties 的 ...