欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SQL有外连接的时候注意过滤条件位置否则会导致网页慢

程序员文章站 2023-11-20 21:14:46
奶奶的,为啥现在五一节只放3天,5月的天气最适合出游了,不过俺们这些苦逼的it男是没法享受了。 一来到公司,项目经理就找到开发leader,说我们网站 页面很慢,让他排查原...
奶奶的,为啥现在五一节只放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