oracle 用EXISTS替代IN

scu2005發表於2009-12-09
  1. 1.用EXISTS替代IN    
  2. 在許多基於基礎表的查詢中,為了滿足一個條件,往往需要對另一個表進行聯接.在這種情況下, 使用EXISTS(或NOT EXISTS)通常將提高查詢的效率.    
  3.   
  4. 低效:    
  5. SELECT *    
  6. FROM EMP (基礎表)    
  7. WHERE EMPNO > 0    
  8. AND DEPTNO IN (SELECT DEPTNO    
  9. FROM DEPT    
  10. WHERE LOC = ‘MELB’)    
  11.        
  12. 高效:    
  13. SELECT *    
  14. FROM EMP (基礎表)    
  15. WHERE EMPNO > 0    
  16. AND EXISTS (SELECT ‘X’    
  17. FROM DEPT    
  18. WHERE DEPT.DEPTNO = EMP.DEPTNO    
  19. AND LOC = ‘MELB’)    
  20.   (相對來說,用NOT EXISTS替換NOT IN 將更顯著地提高效率)    
  21.      
  22. 2. 用NOT EXISTS替代NOT IN    
  23. 在子查詢中,NOT IN子句將執行一個內部的排序和合並. 無論在哪種情況下,NOT IN都是最低效的 (因為它對子查詢中的表執行了一個全表遍歷).  為了避免使用NOT IN ,我們可以把它改寫成外連線(Outer Joins)或NOT EXISTS.    
  24. 例如:    
  25. SELECT …    
  26. FROM EMP    
  27. WHERE DEPT_NO NOT IN (SELECT DEPT_NO    
  28.                         FROM DEPT    
  29.                         WHERE DEPT_CAT=’A’);    
  30.   
  31. 為了提高效率.改寫為:    
  32.   
  33. (方法一: 高效)    
  34. SELECT ….    
  35. FROM EMP A,DEPT B    
  36. WHERE A.DEPT_NO = B.DEPT(+)    
  37. AND B.DEPT_NO IS NULL    
  38. AND B.DEPT_CAT(+) = ‘A’    
  39.   
  40.   
  41. (方法二: 最高效)    
  42. SELECT ….    
  43. FROM EMP E    
  44. WHERE NOT EXISTS (SELECT ‘X’    
  45.                     FROM DEPT D    
  46.                     WHERE D.DEPT_NO = E.DEPT_NO    
  47.                     AND DEPT_CAT = ‘A’);    
  48.   
  49. 本人在使用中發現左外連線效能比not exist更高效,請大家進一步驗證。    
  50. 3.用表連線替換EXISTS    
  51.       通常來說 , 採用表連線的方式比EXISTS更有效率    
  52.       SELECT ENAME    
  53.       FROM EMP E    
  54.       WHERE EXISTS (SELECT ‘X’    
  55.                       FROM DEPT    
  56.                       WHERE DEPT_NO = E.DEPT_NO    
  57.                       AND DEPT_CAT = ‘A’);    
  58.   
  59.     (更高效)    
  60.       SELECT ENAME    
  61.       FROM DEPT D,EMP E    
  62.       WHERE E.DEPT_NO = D.DEPT_NO    
  63.       AND DEPT_CAT = ‘A’ ;    
  64. (在RBO的情況下,前者的執行路徑包括FILTER,後者使用NESTED LOOP)    
  65.   
  66. 4.用EXISTS替換DISTINCT    
  67. 當提交一個包含一對多表資訊(比如部門表和僱員表)的查詢時,避免在SELECT子句中使用DISTINCT. 一般可以考慮用EXIST替換    
  68. 例如:    
  69. 低效:    
  70.     SELECT DISTINCT DEPT_NO,DEPT_NAME    
  71.     FROM DEPT D,EMP E    
  72.     WHERE D.DEPT_NO = E.DEPT_NO    
  73. 高效:    
  74.     SELECT DEPT_NO,DEPT_NAME    
  75.     FROM DEPT D    
  76.     WHERE EXISTS ( SELECT ‘X’    
  77.                     FROM EMP E    
  78.                     WHERE E.DEPT_NO = D.DEPT_NO);    
  79.   EXISTS 使查詢更為迅速,因為RDBMS核心模組將在子查詢的條件一旦滿足後,立刻返回結果.  

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/11536986/viewspace-622018/,如需轉載,請註明出處,否則將追究法律責任。

相關文章