程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> Oracle中SQL的性能優化

Oracle中SQL的性能優化

編輯:Oracle數據庫基礎
 

1、用EXISTS替代IN,NOT EXISTS替代NOT IN: 在子查詢中,NOT 在許多基於基礎表的查詢中,為了滿足一個條件,往往需要對另一個表進行聯接.在這種情況下, 使用EXISTS(或NOT EXISTS)通常將提高查詢的效率.

    SELECT * FROM EMP (基礎表)
    WHERE EMPNO > 0 AND EXISTS (SELECT ‘X' FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO 
       AND LOC = ‘MELB')
 

    2、用Where子句替換HAVING子句: 
    避免使用HAVING子句, HAVING 只會在檢索出所有記錄之後才對結果集進行過濾. 這個處理需要排序,總計等操作. 如果能通過WHERE子句限制記錄的數目,那就能減少這方面的開銷. 
    例如: 
    低效: 

    SELECT REGION,AVG(LOG_SIZE)FROM LOCATION
    GROUP BY REGION HAVING REGION REGION != ‘SYDNEY'
    AND REGION != ‘PERTH'

    高效 

    SELECT REGION,AVG(LOG_SIZE) FROM LOCATION
    WHERE REGION REGION != ‘SYDNEY' AND REGION != ‘PERTH'
    GROUP BY REGION

    3、使用表的別名(Alias)

    當在SQL語句中連接多個表時, 請使用表的別名並把別名前綴於每個Column上.這樣一來,就可以減少解析的時間並減少那些由Column歧義引起的語法錯誤.

    4、用EXISTS替換DISTINCT

    當提交一個包含一對多表信息(比如部門表和雇員表)的查詢時,避免在SELECT子句中使用DISTINCT. 一般可以考慮用EXIST替換 
    例如:

    低效:

    SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D,EMP E
    WHERE D.DEPT_NO = E.DEPT_NO

    高效:

    SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X'
    FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);

    EXISTS 使查詢更為迅速,因為RDBMS核心模塊將在子查詢的條件一旦滿足後,立刻返回結果.

5、用UNION替換OR (適用於索引列)

    通常情況下, 用UNION替換WHERE子句中的OR將會起到較好的效果. 對索引列使用OR將造成全表掃描. 注意, 以上規則只針對多個索引列有效. 如果有column沒有被索引, 查詢效率可能會因為你沒有選擇OR而降低.

    在下面的例子中, LOC_ID 和REGION上都建有索引.

    高效:

    SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION
    WHERE LOC_ID = 10 UNION SELECT LOC_ID , LOC_DESC , REGION
    FROM LOCATION WHERE REGION = “MELBOURNE”

    低效:

   SELECT LOC_ID , LOC_DESC , REGION
   FROM LOCATION WHERE LOC_ID = 10 OR REGION = “MELBOURNE”

     如果你堅持要用OR, 那就需要返回記錄最少的索引列寫在最前面.

    6、用IN來替換OR

    下面的查詢可以被更有效率的語句替換:

    低效:

   SELECT….FROM LOCATION WHERE LOC_ID = 10
   OR LOC_ID = 20 OR LOC_ID = 30

     高效

    SELECT…
    FROM LOCATION WHERE LOC_IN IN (10,20,30); 

    7、WHERE子句中的連接順序.

    ORACLE采用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾.

    例如: (低效,執行時間156.3秒)

    SELECT …
    FROM EMP E WHERE SAL > 50000 AND JOB = ‘MANAGER'
    AND 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO);

    (高效,執行時間10.6秒)

   SELECT … FROM EMP E WHERE 25 < (SELECT COUNT(*) FROM EMP
   WHERE MGR=E.EMPNO) AND SAL > 50000 AND JOB = ‘MANAGER'; 

     8、計算記錄條數 和一般的觀點相反, count(*) 比count(1)稍快 , 當然如果可以通過索引檢索,對索引列的計數仍舊是最快的. 例如 COUNT(EMPNO)

 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved