您的位置:首页 > 数据库 > MySQL

MySql优化实战,详解执行计划

2016-08-02 18:50 357 查看
最近负责了sql优化的工作,其中有一条慢sql,我对他进行了四次优化,在这四次优化中,我学习到了很多关于优化sql的知识,我现在把我的思路和解决方案分享给大家,也分享给未来的我。(里面有几个问题我尚未解决,若有能解决的大侠请联系我,或者在博客留言,不胜感激!微信:cuimiao147)

首先,我先对慢sql执行explain,如图。

发然后主要有,现存在这三个问题1、Using
filesort  2、  Using temporary3、没有用到索引。

先解释下Using filesort:文件排序,即无索引排序

Using temporary:创建临时表

sql概览是这样的:



由图可知,创建索引占用了大部分时间。为什么会创建索引呢?因为有个查询时无索引的排序,在排序的时候创建索引占用了整个查询90%的时间。所以先解决这个问题。

(PS:Using filesort 无索引排序时会出现这种情况,即order by 非索引字段 。)

已经知道原因了,所以解决思路有两个。第一、创建索引,按索引排序。第二、业务允许情况下不使用排序。

但真实的情况是,我的sql中并没有order关键字。那是哪里filesort了呢?

真相是这样滴!group by会默认排序,也就是相当于隐式调用了order!所以要取消排序,可以这样写 :group by 字段 order by null。(这里是我学习到的第一个新知识)

结果优化后在数据量小的情况下耗时从0.425s降到了0.122s,快了4倍,而在数据量稍大的情况下只是从0.748s降到了0.361s,近两倍。所以还需要继续优化。

converting HEAP to MyISAM在之前占用10%的执行时间(优化了很多次,某一次的数据),我砍掉了select后面很多不必要的字段后,这个问题就消失了。原来这个出现的愿意是:查询结果太大时,把结果放在磁盘,导致查询变慢(学到的第二个新知识)

现在的sql概览变成了这样:



主要消耗时间的是Sending data。(到最后也是这个占用了最多时间,一直不知道怎么办,求大神指点)

执行计划看到的问题还剩下 2、 Using temporary 3、没有用到索引。

然后解决Using temporary问题。

这个问题是说明建了临时表,应该被优化。

我这个sql之所以产生这个的原因是GROUP BY非索引字段导致的的。但group by的这个字段是在子查询中取出的,我不知怎么能把他作为索引(不知道有没有办法,求大神指教)。

所以这个里就遗留了下来,没有优化。

然后是添加索引,基本上之前是using where的地方都变成了using index,这次优化直接使小数据情况下降到0.030s,较初始的sql快了14倍,较大数据情况下0.074s快了10倍,但有一个地方加了索引却并没有将using where变成using index,也就是该索引并未被使用。情况是这样的,烦请各位大神支招。

site_id设为索引,查询时site_id in (子查询),这个时候索引失效了,不知道有没有办法进行优化。

(由于室友忘带钥匙,思路断了。。。就记得这么多了,什么脑子。。)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mysql