正在看的ORACLE教程是:Oracle SQL性能優化系列學習三
使用DECODE函數來減少處理時間
使用DECODE函數可以避免重復掃描相同記錄或重復連接相同的表
例如:
SELECT COUNT(*)
SUM(SAL) FROM EMP
WHERE DEPT_NO =
AND ENAME LIKE
SMITH%
;
SELECT COUNT(*)
SUM(SAL)
FROM EMP
WHERE DEPT_NO =
AND ENAME LIKE
SMITH%
;
你可以用DECODE函數高效地得到相同結果
SELECT COUNT(DECODE(DEPT_NO
X
NULL)) D
_COUNT
COUNT(DECODE(DEPT_NO
X
NULL)) D
_COUNT
SUM(DECODE(DEPT_NO
SAL
NULL)) D
_SAL
SUM(DECODE(DEPT_NO
SAL
NULL)) D
_SAL
FROM EMP WHERE ENAME LIKE
SMITH%
;
類似的
DECODE函數也可以運用於GROUP BY 和ORDER BY子句中
整合簡單
無關聯的數據庫訪問
如果你有幾個簡單的數據庫查詢語句
你可以把它們整合到一個查詢中(即使它們之間沒有關系)
例如:
SELECT NAME FROM EMP
WHERE EMP_NO =
;
SELECT NAME FROM DPT
WHERE DPT_NO =
;
SELECT NAME FROM CAT
WHERE CAT_TYPE =
RD
;
上面的
個查詢可以被合並成一個:
SELECT E
NAME
D
NAME
C
NAME FROM CAT C
DPT D
EMP E
DUAL X
WHERE 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(+) =
AND D
DEPT_NO(+) =
AND C
CAT_TYPE(+) =
RD
;
(譯者按: 雖然采取這種方法
效率得到提高
但是程序的可讀性大大降低
所以讀者 還是要權衡之間的利弊)
刪除重復記錄
最高效的刪除重復記錄方法 ( 因為使用了ROWID)
DELETE FROM EMP E
WHERE E
ROWID > (SELECT MIN(X
ROWID)
FROM EMP X
WHERE X
EMP_NO = E
EMP_NO);
用TRUNCATE替代DELETE
當刪除表中的記錄時
在通常情況下
回滾段(rollback segments ) 用來存放可以被恢復的信息
如果你沒有COMMIT事務
ORACLE會將數據恢復到刪除之前的狀態(准確地說是恢復到執行刪除命令之前的狀況)
而當運用TRUNCATE時
回滾段不再存放任何可被恢復的信息
當命令運行後
數據不能被恢復
因此很少的資源被調用
執行時間也會很短
(注
TRUNCATE只在刪除全表適用
TRUNCATE是DDL不是DML)
盡量多使用COMMIT
只要有可能
在程序中盡量多使用COMMIT
這樣程序的性能得到提高
需求也會因為COMMIT所釋放的資源而減少:
COMMIT所釋放的資源:
a
回滾段上用於恢復數據的信息
b
被程序語句獲得的鎖
c
redo log buffer 中的空間
d
Oracle為管理上述
種資源中的內部花費
(注
在使用COMMIT時必須要注意到事務的完整性
現實中效率和事務完整性往往是魚和熊掌不可得兼)
如果DECODE取值為NULL
SUM(NULL)的值是NULL
>如果所有的值都是NULL
SUM(NULL) = NULL 但是只要有一個值不是NULL
SUM() <> NULL 所以原SQL應該沒有什麼邏輯上的問題
關於第八點的個人看法
如果DECODE取值為NULL
SUM(NULL)的值是NULL
不會正常求和的
可以改成如下所示就好了
SELECT COUNT(DECODE(DEPT_NO
X
NULL)) D
_COUNT
COUNT(DECODE(DEPT_NO
X
NULL)) D
_COUNT
SUM(DECODE(DEPT_NO
SAL
)) D
_SAL
SUM(DECODE(DEPT_NO
SAL
)) D
_SAL FROM EMP WHERE ENAME LIKE
SMITH%
;
From:http://tw.wingwit.com/Article/program/Oracle/201404/30542.html