概述
本日发明有个项目应用每次一启动后行使就会导致其它一个应用处事直接瓦解,而这两个应用行使的是同个数据库,颠末排查可以发明是报表应用的某个查询成果导致,而咨询开拓但却查不出是哪条sql,那就只能靠本身排查了..下面是办理的大抵进程。
1、开启慢查询
修改my.ini设置,增进参数
- slow-query-log=1
- slow_query_log_file="epms-slow.log"
- long_query_time=10
修改后重启,调查epms-slow.log日记内容。
2、定位慢sql
从头点击报表模块,选择日期后点击查询,等体系瓦解后,调查日记涉及的慢查询sql
发明题目sql如下:
- select id, parent, project, name
- from zentao.zt_task
- where parent = 0
- /*and exists (select t.parent from zentao.zt_task t where t.parent > 0)*/
- and id in (
- select t.parent from zentao.zt_task t where t.parent > 0
- );
3、查察执行打算
- explain select id, parent, project, name
- from zentao.zt_task
- where parent = 0
- /*and exists (select t.parent from zentao.zt_task t where t.parent > 0)*/
- and id in (
- select t.parent from zentao.zt_task t where t.parent > 0
- );

这里可以看到由于走的全扫,每次都扫5万条,发生笛卡尔积,5万*5万就导致数据库瓦解了。
4、思量用exists改写sql
- explain select id, parent, project, name
- from zentao.zt_task t
- where parent = 0 and exists (
- select a.parent from zentao.zt_task a where a.parent = t.id
- )

这里改写后题目照旧没办理。
5、思量with改写
其后发明zt_task表查询了两次,以是思量with改写来简化,只查一次
- WITH tmp AS ( SELECT * FROM zt_task ) SELECT
- *
- FROM
- tmp t1
- JOIN tmp t2 ON t1.id = t2.parent

好吧,mysql5.7还不支持with改写,只有到mysql 8版本才支持,以是这里只能放弃这种步伐了
6、用子查询join改写
- SELECT
- distinct t1.parent,
- t1.id,
- t1.project,
- t1.NAME
- FROM
- zentao.zt_task t1
- JOIN ( SELECT t.parent FROM zentao.zt_task t WHERE t.parent > 0 ) ta ON t1.id = ta.parent
- AND t1.parent =0


这里要记得去重,改写后查询在1秒内得出功效,满意需求。
总结
通过这道案例必然要记着,多表查询的机能是很差的,虽然,机能差是有一个条件的:数据量大。子查询 = 简朴查询 + 限制查询 + 多表查询 + 统计查询的综合体;
在之前夸大过多表查询不提议各人行使,由于机能很差,可是多表查询最有利的更换者就是子查询,以是子查询(子查询指的就是在一个查询之中嵌套了其他的多少查询)在现实的事变之中行使的相等的多。
(编辑:湖南网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|