SQL有外連接的時候注意過濾條件位置否則會導致網頁慢_Mssql數據庫教程

      編輯Tag賺U幣

      推薦:CMD命令操作MSSQL2005數據庫(命令整理)
      創建數據庫、創建用戶、修改數據的所有者、設置READ_COMMITTED_SNAPSHOT以及備份、日志扥等等,感興趣的朋友可以參考下

      奶奶的,為啥現在五一節只放3天,5月的天氣最適合出游了,不過俺們這些苦逼的IT男是沒法享受了。
      一來到公司,項目經理就找到開發leader,說我們網站 頁面很慢,讓他排查原因。
      一聽說 網站慢,頁面慢哥就來精神了,哥的老本行就是 解決“慢”的問題。
      開發leader 很郁悶的說,我們已經加了 memcache了,20分鐘 cache一次,咋個還是慢呢,
      于是哥就問,那個網頁跑了哪些SQL? 能抓出來讓我看看嗎? 開發Leader 果斷的把SQL 抓了出來。
      經過排查,我們發現了一個SQL確實跑得慢。該SQL 如下
      復制代碼 代碼如下:www.wf0088.com

      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;

      執行計劃如下
      復制代碼 代碼如下:www.wf0088.com

      執行計劃
      ----------------------------------------------------------
      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的條件寫錯位置了
      正確的寫法應該是 下面這樣的
      復制代碼 代碼如下:www.wf0088.com

      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;

      執行計劃如下
      復制代碼 代碼如下:www.wf0088.com

      執行計劃
      ----------------------------------------------------------
      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 游標的使用—游標FOR循環小例子
      游標for循環是在pl/sql塊中使用游標最簡單的方式,它簡化了對游標的處理。當使用游標for循環時,oracle會隱含的打開游標,提取游標數據并關閉游標。

      來源:模板無憂//所屬分類:Mssql數據庫教程/更新時間:2013-05-04
      相關Mssql數據庫教程