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

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐