Oracle SQL效能最佳化系列講座之三(轉)

gugu99發表於2007-08-13
Oracle SQL效能最佳化系列講座之三(轉)[@more@]

  8. 使用DECODE函式來減少處理時間

  使用DECODE函式可以避免重複掃描相同記錄或重複連線相同的表.

  例如:

  SELECT COUNT(*),SUM(SAL) FROM EMPWHERE DEPT_NO = 0020AND ENAME LIKE ‘SMITH%';SELECT COUNT(*),SUM(SAL)FROM EMPWHERE DEPT_NO = 0030AND ENAME LIKE ‘SMITH%';

  你可以用DECODE函式高效地得到相同結果

  SELECT COUNT(DECODE(DEPT_NO,0020,'X',NULL)) D0020_COUNT,COUNT(DECODE(DEPT_NO,0030,'X',NULL)) D0030_COUNT,SUM(DECODE(DEPT_NO,0020,SAL,NULL)) D0020_SAL,SUM(DECODE(DEPT_NO,0030,SAL,NULL)) D0030_SALFROM EMP WHERE ENAME LIKE ‘SMITH%';

  類似的,DECODE函式也可以運用於GROUP BY 和ORDER BY子句中.

  9. 整合簡單,無關聯的資料庫訪問

  如果你有幾個簡單的資料庫查詢語句,你可以把它們整合到一個查詢中(即使它們之間沒有關係)

  例如:

  SELECT NAME FROM EMPWHERE EMP_NO = 1234;SELECT NAME FROM DPTWHERE DPT_NO = 10 ;SELECT NAME FROM CATWHERE CAT_TYPE = ‘RD';

  上面的3個查詢可以被合併成一個:

  SELECT E.NAME , D.NAME , C.NAME FROM CAT C , DPT D , EMP E,DUAL XWHERE NVL(‘X',X.DUMMY) = NVL(‘X',E.ROWID(+))AND NVL(‘X',X.DUMMY) = NVL(‘X',D.ROWID(+))AND NVL(‘X',X.DUMMY) = NVL(‘X',C.ROWID(+))AND E.EMP_NO(+) = 1234AND D.DEPT_NO(+) = 10AND C.CAT_TYPE(+) = ‘RD';

  (譯者按: 雖然採取這種方法,效率得到提高,但是程式的可讀性大大降低,所以讀者 還是要權衡之間的利弊)

  10. 刪除重複記錄

  最高效的刪除重複記錄方法 ( 因為使用了ROWID)

  DELETE FROM EMP EWHERE E.ROWID > (SELECT MIN(X.ROWID)FROM EMP XWHERE X.EMP_NO = E.EMP_NO);

  11. 用TRUNCATE替代DELETE

  當刪除表中的記錄時,在通常情況下, 回滾段(rollback segments ) 用來存放可以被恢復的資訊. 如果你沒有COMMIT事務,ORACLE會將資料恢復到刪除之前的狀態(準確地說是恢復到執行刪除命令之前的狀況) ,而當運用TRUNCATE時, 回滾段不再存放任何可被恢復的資訊.當命令執行後,資料不能被恢復.因此很少的資源被呼叫,執行時間也會很短。(注: TRUNCATE只在刪除全表適用,TRUNCATE是DDL不是DML)

  12. 儘量多使用COMMIT

  只要有可能,在程式中儘量多使用COMMIT, 這樣程式的效能得到提高,需求也會因為COMMIT所釋放的資源而減少:

  COMMIT所釋放的資源:

  a. 回滾段上用於恢復資料的資訊.

  b. 被程式語句獲得的鎖

  c. redo log buffer 中的空間

  d. Oracle為管理上述3種資源中的內部花費

  (注:在使用COMMIT時必須要注意到事務的完整性,現實中效率和事務完整性往往是魚和熊掌不可得兼)

  如果DECODE取值為NULL,SUM(NULL)的值是NULL --&gt如果所有的值都是NULL , SUM(NULL) = NULL 但是隻要有一個值不是NULL,SUM() <> NULL 所以原SQL應該沒有什麼邏輯上的問題

  關於第八點的個人看法:如果DECODE取值為NULL,SUM(NULL)的值是NULL,不會正常求和的。可以改成如下所示就好了: SELECT COUNT(DECODE(DEPT_NO,0020,'X',NULL)) D0020_COUNT, COUNT(DECODE(DEPT_NO,0030,'X',NULL)) D0030_COUNT, SUM(DECODE(DEPT_NO,0020,SAL,0)) D0020_SAL, SUM(DECODE(DEPT_NO,0030,SAL,0)) D0030_SAL FROM EMP WHERE ENAME LIKE ‘SMITH%';


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

相關文章