Oracle 解析器由右至左處理 FROM 子句,最右側表為驅動表。選擇筆數最少的表作為驅動表效能最佳。
TAB1: 16,384 筆 TAB2: 1 筆 SELECT COUNT(*) FROM tab1, tab2; -- 0.96 秒 (tab2 驅動) SELECT COUNT(*) FROM tab2, tab1; -- 26.09 秒 (tab1 驅動)
三表以上:選擇交叉表(被其他表參考的表)作為驅動表。
-- 低效 156.3 秒
SELECT ... FROM emp e WHERE sal > 50000 AND job = 'MANAGER'
AND 25 < (SELECT COUNT(*) FROM emp WHERE mgr = e.empno);
-- 高效 10.6 秒
SELECT ... FROM emp e
WHERE 25 < (SELECT COUNT(*) FROM emp WHERE mgr = e.empno)
AND sal > 50000 AND job = 'MANAGER';
每次 SQL 執行伴隨解析、優化、繫結、區塊讀取等內部動作。
| 方法 | SQL | 評價 |
|---|---|---|
| 1. 多次單獨查詢 | SELECT ... WHERE emp_no=342; SELECT ... WHERE emp_no=291; | 最差 |
| 2. 游標重複開啟 | DECLARE CURSOR c1(e_no) ... OPEN c1(342); OPEN c1(291); | 次差 |
| 3. 單次 Join 查詢 | SELECT a.*, b.* FROM emp a, emp b WHERE a.emp_no=342 AND b.emp_no=291; | 最佳 |
SQL*Plus、Forms、Pro*C 中設定 ARRAYSIZE=200,增加單次網路往返傳輸行數,降低往返頻率。