SQL有外连接的时候注意过滤条件位置

2013年/5月/2日

 

奶奶的,为啥现在五一节只放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

 

 

 

更多相关文章
  • 极客头条新版上线近一个月,我们也在前不久开通了博客专家直推极客头条功能,各位专家同学非常活跃积极支持极客头条,特此感谢! 为了了解各位博客专家大牛的亲身使用感悟,为我们日后极客头条产品改进提供重要参考,特举办本次「面向专家」的极客头条使用体验征文活动. 希望各位专家同学尽情地用博文向我们说出您使用极 ...
  • 美国国家情报总监办公室(ODNI)周一宣布称,对于曾经收集的大量美国电话记录,美国国家安全局(NSA)将会限制数据读取并最终销毁. 今年6月通过的联邦法律结束了NSA针对美国公民电话记录的大规模收集,并且规定NSA销毁已经收集的数据,这归功于前NSA雇员斯诺登的泄露带来的全球范围内的广泛争议. 至今 ...
  • 1 常用函数 1.1   socket() int socket(int family, int type, int protocol); socket()打开一个网络通讯端口,如果成功的话,返回一个文件描述符,应用程序可以像读写文件一样用read/write在网络上收发数据,如果socket()调 ...
  • 本文由阿德马翻译自国外网站,尊重劳动成果,转载请注明出处,谢谢. 本文将详细介绍Appscan功能选项设置的细节,适合E文一般,初次接触Appscan的童鞋参考阅读. Appscan是web应用程序渗透测试舞台上使用最广泛的工具之一.它是一个桌面应用程序,它有助于专业安全人员进行Web应用程序自动化 ...
  • 1 我们今日的窘境 1.1 环境 我们所处的环境是一个追求“革命性技术”的业界.公司追求着多.快.好.省地解决问题的捷径,管理者关注的只是软件进度.发布版本.成本和利润,在他们背后,软件缺陷已经埋了下来.专注代码质量的程序员往往不受青睐,因为他们思考的更多,在开发进度方面往往不尽人意.当项目负责人无 ...
  •      小菜今天发现一个比较有意思的事:万网域名.      万网,IT界无人不晓,现已归阿里所属,它的真实域名为:www.www.net.cn.为什么看起来这么奇怪呢,里边大有文章.      平常我们见到的*.com.*.cn.*.net,是顶级域名,但我们习惯于用www.*.com的方式访问 ...
一周排行
  • 1.建立spakTesk项目,建立scala对象Test 2.Tesk对象的代码如下 package sparkTest /** * Created by jiahong on -2. */ import o ...
  • 看<少有人走的路>,印象比较深刻的是,作者身为心理医生,但他说,他并不是总那么有信心帮助病人恢复,而面对看起来是同样类型的疾病的病人,他也不能采取同样的方式来对待,因为每个病人都有自己的差异,医生都有自己 ...
  • 下面来谈一个比较经典的表达式求值问题,这个问题主要是设计到操作符的优先级.我们通常看到的表达式都是中缀表达式,存在很多优先级差别,而后缀表达式则没有这些优先级问题.下面先看看两种表达式的区别.          中缀 ...
  • Linux的交换分区类似windows的虚拟内存,用来将内存中不用的某些内存页 通过某种算法置换到文件系统中,从而腾出更多的内存来运行其它程序.在机器 的物理内存很小的时候,一般都会通过创建交换分区来提高系统的性能. ...
  • 普通登录oracle的大体流程: sqlplus --> user name & passwd --> host 回到操作系统环境 --> echo %oracle_sid% #装在wind ...
  •    '下面是一个关于VB的农历算法     '日期数据定义方法如下     '前12个字节代表2月为大月或是小月,1为大月30天,0为小月29天:     '第13位为闰月的情况,1为大月30天,0为小月29 ...
  • 听说,金碗公司的聚宝盆项目倒掉了,听说而已,我没有亲见.但我却见过未倒的聚宝盆项目,破破烂烂的定位在国内风光无限的软件开发大潮中,金碗公司上上下下的目光全落在聚宝盆上,就是“重点关照”,金碗十景之一.“重点关照”的真 ...
  • 如此水的01背包,居然让我WA了七次. 开始理解错题意了,弄反了主次关系.总曲目最多是大前提,其次才是歌曲总时间最长. 题意: 在KTV房间里还剩t秒的时间,可以从n首喜爱的歌里面选出若干首(每首歌只能唱一次且如果唱 ...
  • 据科技博客The Next Web援引数据公司Flurry的报告称,iOS和Android设备的普及速度已超过历史上任何一种消费类技术.与最近的一些技术相比,智能设备的普及速度是80年代PC的10倍,90年代互联网的 ...
  • NPOI在.net中的操作Excel 1.读取 using (FileStream stream = new FileStream(@"c:\客户资料.xls", FileMode.Open, F ...