慢SQL产生的主要原因有SQL编写问题、锁等待、业务实例相互干扰对IO/CPU资源征用和服务器硬件等。在业务运行中,由于SQL编写导致的慢SQL的概率最大,故着重从SQL编写的优化入手,并结合具体案例进行说明。
如何查看慢SQL
1. 登录管理控制台。
2. 单击管理控制台左上角的图标,选择区域和项目。
3. 在页面左上角单击图标,选择“ 数据库 > 云数据库 GaussDB”。进入云数据库GaussDB控制台,在左侧导航栏选择“GaussDB(for MySQL)”。
4. 在“实例管理”页面,选择目标实例,单击实例名称,进入“基本信息”页面。
5. 在左侧导航树,单击“日志管理”。
6. 选择“慢日志”页签,查看慢SQL语句的详细信息。慢日志功能支持查看指定执行语句类型或时间段的慢日志记录。
如何进行慢SQL优化
本部分从SQL编写角度介绍慢SQL可进行的优化。
1. 字段类型转换导致不用索引,如字符串类型的不用引号,数字类型的用引号等,这有可能会用不到索引导致全表被扫描。
2. mysql不支持函数转换,所以字段前面不能加函数,否则将用不到索引。
3. 不要在字段前面加减运算。
4. 字符串比较长的可以考虑索引一部分减少索引文件大小,提高写入效率。
5. like %在前面用不到索引。
6. 根据联合索引的第二个及以后的字段单独查询用不到索引。
7. 不要使用select *。
8. 排序请尽量使用升序。
9. or的查询尽量用union代替(Innodb)。
10. 复合索引高选择性的字段排在前面。
11. order by/group by字段包括在索引当中减少排序,效率会更高。
慢SQL优化典型案例
本部分以“mysql不支持函数转换,所以字段前面不能加函数,否则将用不到索引”优化点为例举例说明。
原SQL语句:
SELECT id,title,most_top,view_count,posttime
FROM article where status=3
AND catalog_id in (select catalog_id from catalog where catalog_id=17 or parent_id=17) and
DATEDIFF(NOW(),posttime)<=90 order by most_top desc,posttime desc limit 0,8
原因分析:通过explain可以看出来这个语句执行慢是因为ariticle表扫描了27298行,并进行了排序。
优化步骤:
1. 初步优化,对数据量进行限制。将原SQL语句修改为:
SELECT id,title,most_top,view_count,posttime
FROM article where status=3
AND catalog_id in (select catalog_id from catalog where catalog_id=17 or parent_id=17) and
DATEDIFF(NOW(),posttime)<=90 order by most_top desc,posttime desc limit 0,8
发现进行限制时间后并没有大幅度的提高。原因每次使用datediff运算导致不走索引即慢SQL优化点的第二条。
2. 继续修改,修改为:
SELECT id,title,most_top,view_count,posttime
FROM article where status=3
AND catalog_id in (select catalog_id from catalog where catalog_id=17 or parent_id=17) and
postime>='2017-09-05' order by most_top desc,posttime desc limit 0,8
重新执行SQL后,SQL执行速度大幅提升。