SQL有外连接的时候注意过滤条件位置否则会导致网页慢
江苏路二手房,赣南脐橙,美女 艺术
奶奶的,为啥现在五一节只放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
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!!
点击进行留言回复
相关文章:
-
-
sql某个日期是当年的第几周
/* *周一作为一周的开始 *当年的1月1号所在的周算作第一周 */ CREATE function GetWeekIndexFirstDate ( @...
[阅读全文]
-
-
数据库SQL---范式
1、数据冗余导致的问题:冗余存储、更新异常、插入异常、删除异常。 2、函数依赖:一种完整性约束。 在关系模式r(R)中,α属于R,β属于R。 1)α函数...
[阅读全文]
-
-
数据库SQL---查询
1、查询所有列 select *from emp;--*表示所有的,from emp表示从emp表中查询。 2、查询指定列 select empno,e...
[阅读全文]
-
-
-
-
-
网友评论