ORACLE SQL性能優化系列 (三-2)

 
13. 記錄條數
  
  和一般的點相反, count(*) count(1)稍快 , 當然如果可以通索引,索引列的數仍舊是最快的. 例如 COUNT(EMPNO)
  
  
  
  (者按: CSDN論壇,經對此有相當烈的討論, 作者的點並不十分準確,過實際測試,上述三方法並沒有著的性能差)
  
  
  
  14. Where子句替HAVING子句
  
  
  
  避免使用HAVING子句, HAVING 只會在索出所有記錄之後對結果集過濾. 理需要排序,總計等操作. 如果能通WHERE子句限制記錄的數目,那就能減少方面的開銷.
  
  
  
  例如:
  
  
  
  低效:
  
   SELECT REGIONAVG(LOG_SIZE)
  
   FROM LOCATION
  
   GROUP BY REGION
  
   HAVING REGION REGION != ‘SYDNEY’
  
   AND REGION != ‘PERTH’
  
  
  
  高效
  
   SELECT REGIONAVG(LOG_SIZE)
  
   FROM LOCATION
  
   WHERE REGION REGION != ‘SYDNEY’
  
   AND REGION != ‘PERTH’
  
   GROUP BY REGION
  
  (者按: HAVING 中的條件一般用於一些集合函數的比,COUNT() 等等. 除此而外,一般的條件應該寫在WHERE子句中)
  
  
  
  15. 減少表的查詢
  
  在含有子查詢SQL句中,要特注意減少表的查詢.
  
  
  
  例如:
  
  低效
  
   SELECT TAB_NAME
  
   FROM TABLES
  
   WHERE TAB_NAME = ( SELECT TAB_NAME
  
   FROM TAB_COLUMNS
  
   WHERE VERSION = 604)
  
   AND DB_VER= ( SELECT DB_VER
  
   FROM TAB_COLUMNS
  
   WHERE VERSION = 604)
  
  
  
  高效
  
   SELECT TAB_NAME
  
   FROM TABLES
  
   WHERE (TAB_NAME,DB_VER)
  
   = ( SELECT TAB_NAME,DB_VER)
  
   FROM TAB_COLUMNS
  
   WHERE VERSION = 604)
  
  
  
   Update 多個Column 例子:
  
  低效:
  
   UPDATE EMP
  
   SET EMP_CAT = (SELECT MAX(CATEGORY) FROM EMP_CATEGORIES),
  
   SAL_RANGE = (SELECT MAX(SAL_RANGE) FROM EMP_CATEGORIES)
  
   WHERE EMP_DEPT = 0020;
  
  
  
  高效:
  
   UPDATE EMP
  
   SET (EMP_CAT, SAL_RANGE)
  
   = (SELECT MAX(CATEGORY) , MAX(SAL_RANGE)
  
   FROM EMP_CATEGORIES)
  
   WHERE EMP_DEPT = 0020;
  
  
  
  
  
  16. 內部函數提高SQL效率.
  
  
  
   SELECT H.EMPNO,E.ENAME,H.HIST_TYPE,T.TYPE_DESC,COUNT(*)
  
   FROM HISTORY_TYPE T,EMP E,EMP_HISTORY H
  
   WHERE H.EMPNO = E.EMPNO
  
  AND H.HIST_TYPE = T.HIST_TYPE
  
  GROUP BY H.EMPNO,E.ENAME,H.HIST_TYPE,T.TYPE_DESC;
  
  
  
  通過調用下面的函數可以提高效率.
  
  FUNCTION LOOKUP_HIST_TYPE(TYP IN NUMBER) RETURN VARCHAR2
  
  AS
  
   TDESC VARCHAR2(30);
  
   CURSOR C1 IS
  
   SELECT TYPE_DESC
  
   FROM HISTORY_TYPE
  
   WHERE HIST_TYPE = TYP;
  
  BEGIN
  
   OPEN C1;
  
   FETCH C1 INTO TDESC;
  
   CLOSE C1;
  
   RETURN (NVL(TDESC,’?’));
  
  END;
  
  
  
  FUNCTION LOOKUP_EMP(EMP IN NUMBER) RETURN VARCHAR2
  
  AS
  
   ENAME VARCHAR2(30);
  
   CURSOR C1 IS
  
   SELECT ENAME
  
   FROM EMP
  
   WHERE EMPNO=EMP;
  
  BEGIN
  
   OPEN C1;
  
   FETCH C1 INTO ENAME;
  
   CLOSE C1;
  
   RETURN (NVL(ENAME,’?’));
  
  END;
  
  
  
  SELECT H.EMPNO,LOOKUP_EMP(H.EMPNO),
  
  H.HIST_TYPE,LOOKUP_HIST_TYPE(H.HIST_TYPE),COUNT(*)
  
  FROM EMP_HISTORY H
  
  GROUP BY H.EMPNO , H.HIST_TYPE;
  
  
  
  (者按: 常在論壇中看到如能不能用一個SQL寫出….’ , 殊不知複雜SQL往往牲了行效率. 掌握上面的運用函數解決問題的方法在實際工作中是非常有意)
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章