1. 程式人生 > >包含IN子查詢的SQL語句的優化

包含IN子查詢的SQL語句的優化

當SQL語句中包含in語句時,有時候會極大的影響效能,我們可以把in子查詢用exists子查詢或外連線替代

例子如下:

   1.SQL語句中包含IN子查詢:

Sql程式碼  收藏程式碼
  1. SQL> select * from servers s  
  2.   2   where s.srvr_id = 3333333 or  
  3.   3   s.srvr_id in (select t.srvr_id  
  4.   4                         from serv_inst t  
  5.   5                        where t.si_status = 'Activated'
      
  6.   6                          and t.type = 'UNIX')  
  7.   7  /  
  8. 已選擇11行。  
  9. 執行計劃  
  10. ----------------------------------------------------------  
  11. Plan hash value: 910321333  
  12. --------------------------------------------------------------------------------  
  13. | Id  | Operation          | Name      | Rows  | Bytes | Cost (%CPU)| Time
         |  
  14. --------------------------------------------------------------------------------  
  15. |   0 | SELECT STATEMENT   |           |     6 |   378 |     2   (0)| 00:00:01 |  
  16. |*  1 |  FILTER            |           |       |       |            |          |  
  17. |   2 |   TABLE ACCESS FULL| SERVERS   |    96 |  6048 |     2   (0)| 00:00:01 |  
  18. |*  3 |   TABLE ACCESS FULL| SERV_INST |     2 |    38 |     2   (0)| 00:00:01 |  
  19. --------------------------------------------------------------------------------  
  20. Predicate Information (identified by operation id):  
  21. ---------------------------------------------------  
  22.    1 - filter("S"."SRVR_ID"=3333333 OR  EXISTS (SELECT /*+ */ 0 FROM  
  23.               "SERV_INST" "T" WHERE "T"."SRVR_ID"=:B1 AND "T"."SI_STATUS"='Activated'  
  24.               AND "T"."TYPE"='UNIX'))  
  25.    3 - filter("T"."SRVR_ID"=:B1 AND "T"."SI_STATUS"='Activated' AND  
  26.               "T"."TYPE"='UNIX')  
  27. Note  
  28. -----  
  29.    - dynamic sampling used for this statement  
  30. 統計資訊  
  31. ----------------------------------------------------------  
  32.           0  recursive calls  
  33.           0  db block gets  
  34.         818  consistent gets  
  35.           0  physical reads  
  36.           0  redo size  
  37.        1146  bytes sent via SQL*Net to client  
  38.         385  bytes received via SQL*Net from client  
  39.           2  SQL*Net roundtrips to/from client  
  40.           0  sorts (memory)  
  41.           0  sorts (disk)  
  42.          11  rows processed  
  43. SQL>   

 2.把上面SQL語句改為EXISTS子查詢形式

Sql程式碼  收藏程式碼
  1. SQL> select *  
  2.   2    from servers s  
  3.   3   where s.srvr_id = 3333333 or exists (select 1  
  4.   4                         from serv_inst t  
  5.   5                        where  s.srvr_id = t.srvr_id   
  6.   6                          and t.si_status = 'Activated'  
  7.   7                          and t.type = 'UNIX')  
  8.   8  /  
  9. 已選擇11行。  
  10. 執行計劃  
  11. ----------------------------------------------------------  
  12. Plan hash value: 910321333  
  13. --------------------------------------------------------------------------------  
  14. | Id  | Operation          | Name      | Rows  | Bytes | Cost (%CPU)| Time     |  
  15. --------------------------------------------------------------------------------  
  16. |   0 | SELECT STATEMENT   |           |     6 |   378 |     2   (0)| 00:00:01 |  
  17. |*  1 |  FILTER            |           |       |       |            |          |  
  18. |   2 |   TABLE ACCESS FULL| SERVERS   |    96 |  6048 |     2   (0)| 00:00:01 |  
  19. |*  3 |   TABLE ACCESS FULL| SERV_INST |     2 |    38 |     2   (0)| 00:00:01 |  
  20. --------------------------------------------------------------------------------  
  21. Predicate Information (identified by operation id):  
  22. ---------------------------------------------------  
  23.    1 - filter("S"."SRVR_ID"=3333333 OR  EXISTS (SELECT /*+ */ 0 FROM  
  24.               "SERV_INST" "T" WHERE "T"."SRVR_ID"=:B1 AND "T"."SI_STATUS"='Activated'  
  25.               AND "T"."TYPE"='UNIX'))  
  26.    3 - filter("T"."SRVR_ID"=:B1 AND "T"."SI_STATUS"='Activated' AND  
  27.               "T"."TYPE"='UNIX')  
  28. Note  
  29. -----  
  30.    - dynamic sampling used for this statement  
  31. 統計資訊  
  32. ----------------------------------------------------------  
  33.           0  recursive calls  
  34.           0  db block gets  
  35.         818  consistent gets  
  36.           0  physical reads  
  37.           0  redo size  
  38.        1146  bytes sent via SQL*Net to client  
  39.         385  bytes received via SQL*Net from client  
  40.           2  SQL*Net roundtrips to/from client  
  41.           0  sorts (memory)  
  42.           0  sorts (disk)  
  43.          11  rows processed  
  44. SQL>   

3.改成另一種外連線的方式

Sql程式碼  收藏程式碼
  1. SQL> select distinct s.*  
  2.   2    from servers s  
  3.   3    left join serv_inst t on s.srvr_id = t.srvr_id  
  4.   4                         and t.si_status = 'Activated'  
  5.   5                         and t.type = 'UNIX'  
  6.   6   where ((t.siid is not nullor (t.siid is null and s.srvr_id = 3333333))  
  7.   7  /  
  8. 已選擇11行。  
  9. 執行計劃  
  10. ----------------------------------------------------------  
  11. Plan hash value: 2837582902  
  12. ----------------------------------------------------------------------------------  
  13. | Id  | Operation            | Name      | Rows  | Bytes | Cost (%CPU)| Time     |  
  14. ----------------------------------------------------------------------------------  
  15. |   0 | SELECT STATEMENT     |           |    96 |  8448 |     7  (29)| 00:00:01 |  
  16. |   1 |  HASH UNIQUE         |           |    96 |  8448 |     7  (29)| 00:00:01 |  
  17. |*  2 |   FILTER             |           |       |       |            |          |  
  18. |*  3 |    HASH JOIN OUTER   |           |    96 |  8448 |     6  (17)| 00:00:01 |  
  19. |   4 |     TABLE ACCESS FULL| SERVERS   |    96 |  6048 |     2   (0)| 00:00:01 |  
  20. |*  5 |     TABLE ACCESS FULL| SERV_INST |    57 |  1425 |     3   (0)| 00:00:01 |  
  21. ----------------------------------------------------------------------------------  
  22. Predicate Information (identified by operation id):  
  23. ---------------------------------------------------  
  24.    2 - filter("T"."SIID" IS NOT NULL OR "T"."SIID" IS NULL AND  
  25.               "S"."SRVR_ID"=3333333)  
  26.    3 - access("S"."SRVR_ID"="T"."SRVR_ID"(+))  
  27.    5 - filter("T"."TYPE"(+)='UNIX' AND "T"."SI_STATUS"(+)='Activated')  
  28. Note  
  29. -----  
  30.    - dynamic sampling used for this statement  
  31. 統計資訊  
  32. ----------------------------------------------------------  
  33.           0  recursive calls  
  34.           0  db block gets  
  35.          12  consistent gets  
  36.           0  physical reads  
  37.           0  redo size  
  38.        1154  bytes sent via SQL*Net to client  
  39.         385  bytes received via SQL*Net from client  
  40.           2  SQL*Net roundtrips to/from client  
  41.           0  sorts (memory)  
  42.           0  sorts (disk)  
  43.          11  rows processed  
  44. SQL>   

 4.另一種外連線的寫法

Sql程式碼  收藏程式碼
  1. SQL> select distinct s.*  
  2.   2    from servers s, serv_inst t  
  3.   3   where s.srvr_id = t.srvr_id(+)  
  4.   4     and t.si_status(+) = 'Activated'  
  5.   5     and t.type(+) = 'UNIX'  
  6.   6     and ((t.siid is not nullor (t.siid is null and s.srvr_id = 3333333))  
  7.   7  /  
  8. 已選擇11行。  
  9. 執行計劃  
  10. ----------------------------------------------------------  
  11. Plan hash value: 2837582902  
  12. ----------------------------------------------------------------------------------  
  13. | Id  | Operation            | Name      | Rows  | Bytes | Cost (%CPU)| Time     |  
  14. ----------------------------------------------------------------------------------  
  15. |   0 | SELECT STATEMENT     |           |    96 |  8448 |     7  (29)| 00:00:01 |  
  16. |   1 |  HASH UNIQUE         |           |    96 |  8448 |     7  (29)| 00:00:01 |  
  17. |*  2 |   FILTER             |           |       |       |            |          |  
  18. |*  3 |    HASH JOIN OUTER   |           |    96 |  8448 |     6  (17)| 00:00:01 |  
  19. |   4 |     TABLE ACCESS FULL| SERVERS   |    96 |  6048 |     2   (0)| 00:00:01 |  
  20. |*  5 |     TABLE ACCESS FULL| SERV_INST |    57 |  1425 |     3   (0)| 00:00:01 |  
  21. ----------------------------------------------------------------------------------  
  22. Predicate Information (identified by operation id):  
  23. ---------------------------------------------------  
  24.    2 - filter("T"."SIID" IS NOT NULL OR "T"."SIID" IS NULL AND  
  25.               "S"."SRVR_ID"=3333333)  
  26.    3 - access("S"."SRVR_ID"="T"."SRVR_ID"(+))  
  27.    5 - filter("T"."SI_STATUS"(+)='Activated' AND "T"."TYPE"(+)='UNIX')  
  28. Note  
  29. -----  
  30.    - dynamic sampling used for this statement  
  31. 統計資訊  
  32. ----------------------------------------------------------  
  33.           0  recursive calls  
  34.           0  db block gets  
  35.          12  consistent gets  
  36.           0  physical reads  
  37.           0  redo size  
  38.        1154  bytes sent via SQL*Net to client  
  39.         385  bytes received via SQL*Net from client  
  40.           2  SQL*Net roundtrips to/from client  
  41.           0  sorts (memory)  
  42. 相關推薦

    包含IN查詢SQL語句優化

    當SQL語句中包含in語句時,有時候會極大的影響效能,我們可以把in子查詢用exists子查詢或外連線替代 例子如下:    1.SQL語句中包含IN子查詢: Sql程式碼   SQL> select * from servers s     2   w

    分頁用到的查詢sql語句

    nbsp 說明 子查詢 src bsp sql img http ges 說明(2017-8-31 23:30:22): 1. 分頁用到的子查詢sql語句 2. 記住的意思就是背過^_^ 3. 還有一個top語句,查一查 分頁用到的子查詢sql語句

    mysql in 查詢 效率慢 優化(轉)

    現在的CMS系統、部落格系統、BBS等都喜歡使用標籤tag作交叉連結,因此我也嚐鮮用了下。但用了後發現我想查詢某個tag的文章列表時速度很慢,達到5秒之久!百思不解(後來終於解決),我的表結構是下面這樣的,文章只有690篇。 文章表article(id,title,content) 標籤表tag(tid,

    Sql語句優化-查詢兩表不同行NOT IN、NOT EXISTS、連接查詢Left Join

    exists join ngs sdn 連接查詢 blog 建議 開發 word 在實際開發中,我們往往需要比較兩個或多個表數據的差別,比較那些數據相同那些數據不相同,這時我們有一下三種方法可以使用:1. IN或NOT IN,2. EXIST或NOTEXIST,

    Sql語句優化-查詢兩表不同行NOT IN、NOT EXISTS、連線查詢Left Join

    在實際開發中,我們往往需要比較兩個或多個表資料的差別,比較那些資料相同那些資料不相同,這時我們有一下三種方法可以使用:1. IN或NOT IN,2. EXIST或NOTEXIST,3.使用連線查詢(inner join,left join 或者 right join)。

    MySQL5.7效能優化系列(二)——SQL語句優化(2)——查詢-派生表-檢視--概述

    章節內容: 使用Semi-join連線優化子查詢、派生表、檢視 使用Materialization優化子查詢 優化派生表、檢視 使用Exist 策略優化子查詢 概述 in或者any子查詢 MySQL查詢優化器具有不同的策略來評估子查詢。對於IN(

    關於T-SQL中exists或者not exists查詢的“偽優化”的做法

    png tro ges width 9.png 當前 color 盡心 alt 問題起源 在使用t-sql中的exists(或者not exists)子查詢的時候,不知道什麽時候開始,發現一小部分人存在一種“偽優化”的一些做法,並且向不明真相

    【mysql優化五】——sql語句優化查詢

    前言 上篇講解了索引搜尋優化,其實索引只是sql查詢優化的一部分,本篇主要講解的是sql優化主要要優化的部分! 內容 一.order by 優化 orderby最好使用index排序方式,避免使

    警惕 MySql 更新 sql 的 WHERE 從句中的 IN() 查詢時出現的效能陷阱

    mer_stage 表有 216423 條記錄,DDL:CREATE TABLE `mer_stage` ( `STAGE_ID` int(11) NOT NULL AUTO_INCREMENT, `MER_ID` int(11) NOT NULL, `MER_C

    sql語句優化:用join取代not in

    寫了好幾個頁面,速度都上不去,瓶頸在於SQL查詢。太多的表,太多的not in,總是從一大推表和資料中篩選出一點資料。看了很多關於SQL優化的文章,都強烈要求不要太多使用not in查詢,最好用表連線來取代它。如:select ID,name from Table_A wh

    SQL IN 查詢返回多個值

    下午遇到一個問題,IN子查詢返回多個值。 網上查了很多文件,資料,都沒收穫。 問了技術群的同僚,竟然還被嘲笑了。IN 怎麼可能匹配多個欄位呢! 個人印象中曾經在哪裡見到過,所以就覺得不服氣。自己慢慢地去試,試出來了。 我們常用的IN 操作是這樣的: s

    Sql語句優化之用exists、not exists替代in、not in

    在許多基於基礎表的查詢中,為了滿足一個條件,往往需要對另一個表進行聯接。在這種情況下, 使用exists(或not exists)通常將提高查詢的效率。在子查詢中,not in子句將執行一個內部的排序和合並。無論在哪種情況下,not in都是最低效的 (因為它對子查詢中的表

    MySQL Execution Plan--IN查詢包含超多值引發的查詢異常1

    pos cos table HERE lock code 5.1 pic key ======================================================================= SQL語句: SELECT wave_n

    提高系統性能——對SQL語句優化的思考

    http art pos select 語句 聯合 data 過程 情況 軟件在研發的過程中自始至終都在留意著系統的可擴展性。但與此同一時候也在關註著系統的性能,SQL語句作為系統性能的一環不容忽視。從今天開始結合開發的經驗,談一下我對SQL語句優化的理

    SQL語句優化

    函數 提高 我們 查詢 str ont ransac pro sys 1、在查詢中不要使用“select *” 檢索不必要的列會帶來額外的系統開銷,有句話叫做“該省的則省”; 2、在select清單中避免不必要的列,在連接條件中避免不必要的表; 3、不要在子查詢中使用co

    基本的查詢sql語句

    sql 查詢 基本 day03 基本的查詢sql語句一、概述: 學習MySQL數據庫中一定要學會sql的查詢功能,說白了,使用數據庫就是存儲數據,查詢數據,使用這些數據的一個過程。只有查看了才知道我們是否存儲成功,是否可以直接使用這些數據。二、具體的sql 1、查詢數據庫的基本語法:

    常用的SQL語句優化方法

    臨時表 數據 arch ediff 重復 red pac eight code 1、應盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。 2、對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order

    SQL語句優化系列四(Oracle數據庫日期格式轉換)

    fun ont 如果 etime 當前時間 字符轉換函數 dual minute nbsp Oracle數據庫日期格式轉換 select sysdate from dual select to_char(sysdate,‘yyyy/mm/dd hh24:mi:ss‘) as

    SQL語句優化系列一

    sql語句 sid 前綴 別名 text pre 操作 解析 歧義 SQL語句優化 1.SELECT 子句中避免使用‘* ’ 2.使用表的別名 (Alias) 當在 SQL 語句中連接多個表時 , 請使用表的別名並把別名前綴於每個 Column 上。這樣一來,就可以減

    Python 爬蟲 大量數據清洗 ---- sql語句優化

    any 語句 sql語句優化 並且 大於 設有 sql 解決問題 sql語句 1. 問題描述 在做爬蟲的時候,數據量很大,大約有五百百萬條數據,假設有個字段是conmany_name(拍賣公司名稱),我們現在需要從五百萬條數據裏面查找出來五十家拍賣公司,  並且要