首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle SQL 效能優化系列 (九):表別名、EXISTS 替代 IN、NOT EXISTS 替代 NOT IN

     編輯:Oracle 資料庫相關知識

本系列第九篇,聚焦三項高頻優化技巧。

17. 使用表別名 (Alias)

多表聯結時,為每個表指定別名並冠於所有欄位前。效益:

  • 減少解析時間 (解析器無需搜尋欄位所屬表)。
  • 避免「欄位歧義」語法錯誤 (同名欄位存在於多表)。
-- 不佳
SELECT empno, ename, dname FROM emp, dept WHERE emp.deptno = dept.deptno;

-- 推薦
SELECT e.empno, e.ename, d.dname
FROM emp e, dept d
WHERE e.deptno = d.deptno;

18. 用 EXISTS 替代 IN

子查詢作為篩選條件時,EXISTS 通常比 IN 高效。

-- 低效 (IN)
SELECT * FROM emp
WHERE empno > 0
  AND deptno IN (SELECT deptno FROM dept WHERE loc = 'MELB');

-- 高效 (EXISTS)
SELECT * FROM emp e
WHERE e.empno > 0
  AND EXISTS (SELECT 'X' FROM dept d
              WHERE d.deptno = e.deptno AND d.loc = 'MELB');

原理:EXISTS 只需檢查是否存在滿足條件的列,一旦找到即停止;IN 需物化子查詢結果集並排序/合併。

19. 用 NOT EXISTS 替代 NOT IN (效能差異最大)

NOT IN 是最低效寫法:對子查詢表全表掃描 + 排序合併。

-- 低效 (NOT IN)
SELECT ... FROM emp
WHERE dept_no NOT IN (SELECT dept_no FROM dept WHERE dept_cat = 'A');

-- 方法一:外連接 (高效)
SELECT ... FROM emp a, dept b
WHERE a.dept_no = b.dept_no(+)
  AND b.dept_no IS NULL
  AND b.dept_cat(+) = 'A';

-- 方法二:NOT EXISTS (最高效)
SELECT ... FROM emp e
WHERE NOT EXISTS (SELECT 'X' FROM dept d
                  WHERE d.dept_no = e.dept_no
                    AND d.dept_cat = 'A');

注意:NOT IN 遇到子查詢含 NULL 會回傳零列 (邏輯陷阱);NOT EXISTS 無此問題。


養成「優先用 EXISTS/NOT EXISTS、必加表別名」習慣,能消除大多數子查詢效能隱患。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved