奶奶的,为啥现在五一节只放3天,5月的天气最适合出游了,不过俺们这些苦逼的it男是没法享受了。
一来到公司,项目经理就找到开发leader,说我们网站 页面很慢,让他排查原因。
一听说 网站慢,页面慢哥就来精神了,哥的老本行就是 解决“慢”的问题。
开发leader 很郁闷的说,我们已经加了 memcache了,20分钟 cache一次,咋个还是慢呢,
于是哥就问,那个网页跑了哪些sql? 能抓出来让我看看吗? 开发leader 果断的把sql 抓了出来。
经过排查,我们发现了一个sql确实跑得慢。该sql 如下
复制代码 代码如下:
select *
from (select u.name universityname,
u.id universityid,
count(a.signupnumber) playercnt
from t_b_university u
left join t_d_education e
on e.university_id = u.id
left join t_d_video_player a
on a.user_id = e.user_id
and e.isdefault = 1
and e.isvalid = 1
and a.auditstatus = 1
and a.isvalid = 1
left join t_d_user c
on a.user_id = c.id
and c.isvalid = 1
where u.region_code like ‘43%’
group by u.name, u.id)
order by playercnt desc;
执行计划如下
复制代码 代码如下:
执行计划
———————————————————-
plan hash value: 3938743742
——————————————————————————————–
| id | operation | name | rows | bytes | cost (%cpu)| time |
——————————————————————————————–
| 0 | select statement | | 142 | 10366 | 170 (3)| 00:00:03 |
| 1 | sort order by | | 142 | 10366 | 170 (3)| 00:00:03 |
| 2 | hash group by | | 142 | 10366 | 170 (3)| 00:00:03 |
|* 3 | hash join right outer| | 672 | 49056 | 168 (2)| 00:00:03 |
|* 4 | table access full | t_d_user | 690 | 5520 | 5 (0)| 00:00:01 |
| 5 | nested loops outer | | 672 | 43680 | 162 (1)| 00:00:02 |
|* 6 | hash join outer | | 672 | 37632 | 14 (8)| 00:00:01 |
|* 7 | table access full | t_b_university | 50 | 2050 | 8 (0)| 00:00:01 |
| 8 | table access full | t_d_education | 672 | 10080 | 5 (0)| 00:00:01 |
| 9 | view | | 1 | 9 | 0 (0)| 00:00:01 |
|* 10 | filter | | | | | |
|* 11 | table access full| t_d_video_player | 1 | 15 | 3 (0)| 00:00:01 |
——————————————————————————————–
predicate information (identified by operation id):
—————————————————
3 – access(“a”.”user_id”=”c”.”id”(+))
4 – filter(“c”.”isvalid”(+)=1)
6 – access(“e”.”university_id”(+)=”u”.”id”)
7 – filter(“u”.”region_code” like ‘43%’)
10 – filter(“e”.”isvalid”=1 and “e”.”isdefault”=1)
11 – filter(“a”.”user_id”=”e”.”user_id” and “a”.”auditstatus”=1 and
“a”.”isvalid”=1)
大家能发现这个sql 的问题吗? 这个 sql 之所以跑得慢是因为开发人员把sql的条件写错位置了
正确的写法应该是 下面这样的
复制代码 代码如下:
select *
from (select u.name universityname,
u.id universityid,
count(a.signupnumber) playercnt
from t_b_university u
left join t_d_education e
on e.university_id = u.id
and e.isdefault = 1
and e.isvalid = 1
left join t_d_video_player a
on a.user_id = e.user_id
and a.auditstatus = 1
and a.isvalid = 1
left join t_d_user c
on a.user_id = c.id
and c.isvalid = 1
where u.region_code like ‘43%’
group by u.name, u.id)
order by playercnt desc;
执行计划如下
复制代码 代码如下:
执行计划
———————————————————-
plan hash value: 2738827747
———————————————————————————————
| id | operation | name | rows | bytes | cost (%cpu)| time |
———————————————————————————————
| 0 | select statement | | 142 | 11218 | 25 (16)| 00:00:01 |
| 1 | sort order by | | 142 | 11218 | 25 (16)| 00:00:01 |
| 2 | hash group by | | 142 | 11218 | 25 (16)| 00:00:01 |
|* 3 | hash join right outer | | 301 | 23779 | 23 (9)| 00:00:01 |
|* 4 | table access full | t_d_user | 690 | 5520 | 5 (0)| 00:00:01 |
|* 5 | hash join right outer| | 301 | 21371 | 17 (6)| 00:00:01 |
|* 6 | table access full | t_d_video_player | 78 | 1170 | 3 (0)| 00:00:01 |
|* 7 | hash join outer | | 301 | 16856 | 14 (8)| 00:00:01 |
|* 8 | table access full | t_b_university | 50 | 2050 | 8 (0)| 00:00:01 |
|* 9 | table access full | t_d_education | 301 | 4515 | 5 (0)| 00:00:01 |
———————————————————————————————
predicate information (identified by operation id):
—————————————————
3 – access(“a”.”user_id”=”c”.”id”(+))
4 – filter(“c”.”isvalid”(+)=1)
5 – access(“a”.”user_id”(+)=”e”.”user_id”)
6 – filter(“a”.”auditstatus”(+)=1 and “a”.”isvalid”(+)=1)
7 – access(“e”.”university_id”(+)=”u”.”id”)
8 – filter(“u”.”region_code” like ‘43%’)
9 – filter(“e”.”isdefault”(+)=1 and “e”.”isvalid”(+)=1)
之前sql要跑至少5秒以上,现在0.1秒能出结果。
各位童鞋,sql 有外连接的时候,要注意过滤条件的位置,记住啦!!!
有sql 需要优化的 欢迎加入 qq 群 220761024 申请注明 来自csdn