mysql临时表产生的执行效率问题改进(转)
- 问题:
近日,线上MySQL查出一个慢sql,每次都要查询1000ms以上,严重影响用户体验
今得空去诊断一番,记录如下:
sql原句:
- SELECT r.object_id AS cardId, count(1) AS attachs FROM hzresource_object r
- LEFT JOIN
- ( SELECT card_id FROM card_member WHERE user_id = #uid# and card_member.deleted=0
- UNION
- SELECT card_id FROM card_subscribed where user_id = #uid# and card_subscribed.deleted=0
- ) m ON r.object_id = m.card_id
- WHERE r.object_type = #objectType# AND r.deleted = 0
- GROUP BY r.object_id;
- 解决问题:
由于对数据库优化一知半解,完全无从下手,只能求助度娘和谷哥了,试验了各种方法,都不见效果
几番周折之后,最终把注意力集中到了临时表上,因为explain查看执行计划,可以看到Using temporary
MySQL在执行SQL查询时可能会用到临时表,一般情况下,用到临时表就意味着性能较低。
于是想办法修改sql语句,摒弃临时表,修改如下:
- SELECT r.object_id AS cardId, count(1) AS attachs FROM hzresource_object r
- WHERE r.object_type = #objectType# AND r.deleted = 0 and r.object_id in (
- SELECT card_id FROM card_member WHERE user_id = #uid# and card_member.deleted=0
- UNION
- SELECT card_id FROM card_subscribed where user_id = #uid# and card_subscribed.deleted=0
- )
- GROUP BY r.object_id;
即把语句给拆分成两个sql语,用in操作拼接
- 本机测试:
优化前执行时间1040ms,优化后执行时间:85ms,执行速度是原来的12倍多!赞
- PS:
常理我们都会排斥用in操作,用union替换,那为什么这里用in会更快呢?
带着问题,接着去网上找,原来:
sql执行会生成一个巨大的临时表,当内存放不下时,要全部copy 到磁盘,导致IO飙升,时间开销增大。
额外收获知识收藏如下:
- 临时表存储
MySQL临时表分为“内存临时表”和“磁盘临时表”,其中内存临时表使用MySQL的MEMORY存储引擎,磁盘临时表使用MySQL的MyISAM存储引擎;
一般情况下,MySQL会先创建内存临时表,但内存临时表超过配置指定的值后,MySQL会将内存临时表导出到磁盘临时表;
- 使用临时表的场景
1)ORDER BY子句和GROUP BY子句不同, 例如:ORDERY BY price GROUP BY name;
2)在JOIN查询中,ORDER BY或者GROUP BY使用了不是第一个表的列 例如:SELECT * from TableA, TableB ORDER BY TableA.price GROUP by TableB.name
3)ORDER BY中使用了DISTINCT关键字 ORDERY BY DISTINCT(price)
4)SELECT语句中指定了SQL_SMALL_RESULT关键字 SQL_SMALL_RESULT的意思就是告诉MySQL,结果会很小,请直接使用内存临时表,不需要使用索引排序 SQL_SMALL_RESULT必须和GROUP BY、DISTINCT或DISTINCTROW一起使用 一般情况下,我们没有必要使用这个选项,让MySQL服务器选择即可。
- 直接使用磁盘临时表的场景
1)表包含TEXT或者BLOB列;
2)GROUP BY 或者 DISTINCT 子句中包含长度大于512字节的列;
3)使用UNION或者UNION ALL时,SELECT子句中包含大于512字节的列;
- 表的设计原则
使用临时表一般都意味着性能比较低,特别是使用磁盘临时表,性能更慢,因此我们在实际应用中应该尽量避免临时表的使用。 常见的避免临时表的方法有:
1)创建索引:在ORDER BY或者GROUP BY的列上创建索引;
2)分拆很长的列:一般情况下,TEXT、BLOB,大于512字节的字符串,基本上都是为了显示信息,而不会用于查询条件, 因此表设计的时候,应该将这些列独立到另外一张表。
- SQL优化
如果表的设计已经确定,修改比较困难,那么也可以通过优化SQL语句来减少临时表的大小,以提升SQL执行效率。
常见的优化SQL语句方法如下:
1)拆分SQL语句
临时表主要是用于排序和分组,很多业务都是要求排序后再取出详细的分页数据,这种情况下可以将排序和取出详细数据拆分成不同的SQL,以降低排序或分组时临时表的大小,提升排序和分组的效率,我们的案例就是采用这种方法。
2)优化业务,去掉排序分组等操作
有时候业务其实并不需要排序或分组,仅仅是为了好看或者阅读方便而进行了排序,例如数据导出、数据查询等操作,这种情况下去掉排序和分组对业务也没有多大影响。
- 如何判断使用了临时表?
使用explain查看执行计划,Extra列看到Using temporary就意味着使用了临时表。
- 小结:
可见, 完全颠覆了对in操作符的认识,凡事儿都是要分情况讨论的
mysql临时表产生的执行效率问题改进(转)的更多相关文章
- mySQL数据库Sql语句执行效率检查--Explain命令
mysql性能的检查和调优方法 Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看SQL语句的执行效 果,可以帮助选择更好的 ...
- MySQL查看SQL语句执行效率
Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看 SQL 语句的执行效 果,可以帮助选择更好的索引和优化查询语句,写出更好 ...
- MySQL查看SQL语句执行效率(转)
Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看 SQL 语句的执行效 果,可以帮助选择更好的索引和优化查询语句,写出更好 ...
- mysql 查看语句的执行效率
EXPLAIN 一.用途: 1.什么时候必须为表加入索引以得到一个使用索引找到记得的更快的select 2.知道优化器是否以一个最佳次序联结表. <官方的关于explain的文档在http:// ...
- mysql is not null 执行效率低
a表字段类型为int b表字段类型为varchar a left join b时如果查询条件是is not null,效率很快,is null 效率很低 后来两者改为同类型 int,效率很高
- mysql优化(三)–explain分析sql语句执行效率
mysql优化(三)–explain分析sql语句执行效率 mushu 发布于 11个月前 (06-04) 分类:Mysql 阅读(651) 评论(0) Explain命令在解决数据库性能上是第一推荐 ...
- Mysql explain分析sql语句执行效率
mysql优化–explain分析sql语句执行效率 Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看SQL语句的执行效 ...
- Mysql 定位执行效率低的sql 语句
一.通过MySQL慢查询日志定位执行效率低的SQL语句. MySQL通过慢查询日志定位那些执行效率较低的SQL 语句,用--log-slow-queries[=file_name]选项启动时,mysq ...
- php中使用mysqli和pdo扩展,测试mysql数据库的执行效率。
<?php /** * 测试pdo和mysqli的执行效率 */ header("Content-type:text/html;charset=utf-8"); //通过pd ...
随机推荐
- 17个CSS知识点整理
1.对WEB标准以及W3C的理解与认识 标签闭合.标签小写.不乱嵌套.提高搜索机器人搜索几率:使用外链css和js脚本.结构行为表现的分离.文件下载与页面速度更快:内容能被更多的用户所访问.内容能被更 ...
- 百度地图的demo提示key验证错误!错误码:230;
在已经有BaiduMap的APIKey后使用AndroidStudio导入Baidu地图的as版的demo,提示key验证错误!错误码:230; 首先,因为百度地图demo中用自己的keystore文 ...
- 一圖讓你看懂javascript原型鏈
每個對象的原型(protype)是一個對象 每個對象都有一個內置屬性protype(__pro__)指向一個對象
- QVariant类及QVariant与自定义数据类型转换的方法
这个类型相当于是Java里面的Object,它把绝大多数Qt提供的数据类型都封装起来,起到一个数据类型“擦除”的作用.比如我们的 table单元格可以是string,也可以是int,也可以是一个颜色值 ...
- TCP长连接保持连接状态TCP keepalive设置
如有转载,请注明出处:http://blog.csdn.net/embedded_sky/article/details/42077321 作者:super_bert@csdn 对于TCP长连接保活是 ...
- Linux中添加快捷
执行操作比较快捷: 1.R3 CGP平台下OMU系统中: Linux 版本:2.6.16.60-0.21-bigsmp vi /etc/profile 2.R2 Linux版本2.6.5-7.244- ...
- savReaderWriter 模块的使用
作用: 由于python可以辅助数据分析和数据挖掘,读取文件, 而savReaderWriter模块就是为此而设计. 官网 :http://pythonhosted.org/savReaderWrit ...
- python-函数中的参数类型和可变参数解析
最近,在学习python,天天抱着廖雪峰的教材苦练,https://www.liaoxuefeng.com/ 但廖老毕竟是如此的才华盈溢,我这等小辈真是读起来教程都有些费力. 关于python-函数中 ...
- (转)OpenGL ES编程入门资源集合
出自:http://blog.csdn.net/u013467442/article/details/44498125 OpenGL ES 2.0中文手册:http://www.dreami ...
- Obj格式模型 读取
OBJ文件的结构 在一个OBJ文件中,首先有一些以v.vt或vn前缀开头的行指定了所有的顶点.纹理坐标.法线的坐标.然后再由一些以f开头的行指定每一个三角形所对应的顶点.纹理坐标和法线的索引.在顶点. ...