本章重點講解 MERGE 語句在多表關聯更新場景下對比傳統 UPDATE ... WHERE EXISTS 的性能優勢,並介紹 WITH CHECK OPTION 視圖繞過 CHECK 約束不能引用 SYSDATE 的限制。
-- 直接建表會報 ORA-02436
CREATE TABLE ttt (create_date DATE CHECK (create_date > SYSDATE));
-- 解法:視圖 + WITH CHECK OPTION
INSERT INTO (SELECT empno, ename, hiredate FROM scott.emp
WHERE hiredate <= SYSDATE WITH CHECK OPTION)
VALUES (9999, 'test', SYSDATE+1); -- 報錯 ORA-01402 違反視圖條件
INSERT INTO (SELECT empno, ename, hiredate FROM scott.emp
WHERE hiredate <= SYSDATE WITH CHECK OPTION)
VALUES (9999, 'test', SYSDATE-1); -- 成功
場景:將 emp_bk.dname 根據 dept_bk 更新,條件 dname IN ('ACCOUNTING','RESERCH')。
-- 傳統 UPDATE
UPDATE lhr.emp_bk a
SET a.dname = (SELECT b.dname FROM lhr.dept_bk b
WHERE b.deptno=a.deptno AND b.dname IN ('ACCOUNTING','RESERCH'))
WHERE EXISTS (SELECT 1 FROM lhr.dept_bk b
WHERE b.deptno=a.deptno AND b.dname IN ('ACCOUNTING','RESERCH'));
-- MERGE 改寫
MERGE INTO lhr.emp_bk a
USING (SELECT dname, deptno FROM lhr.dept_bk
WHERE dname IN ('ACCOUNTING','RESERCH')) bb
ON (bb.deptno = a.deptno)
WHEN MATCHED THEN UPDATE SET a.dname = bb.dname;
| 指標 | UPDATE | MERGE | 提升 |
|---|---|---|---|
| Consistent Gets | 121 | 38 | 68% ↓ |
| Physical Reads | 9 | 1 | 89% ↓ |
| Redo Size | 3012 | 1872 | 38% ↓ |
| Recursive Calls | 69 | 20 | 71% ↓ |
執行計劃顯示 UPDATE 掃描 dept_bk 兩次 (HASH JOIN SEMI + FILTER),MERGE 僅一次 HASH JOIN。
WITH CHECK OPTION 視圖可實現業務規則在 DML 時的強制驗證,繞過 CHECK 約束限制。