每執行一條 SQL 陳述句,Oracle 內部都會進行解析、優化、綁定變數、讀取資料區塊等動作。減少資料庫往返次數,能直接降低系統負擔。
方法 1:最低效(兩次獨立查詢)
SELECT emp_name, salary, grade FROM emp WHERE emp_no = 342;
SELECT emp_name, salary, grade FROM emp WHERE emp_no = 291;
兩次完整的解析與執行流程。
方法 2:次低效(PL/SQL 游標迴圈)
DECLARE
CURSOR c1 (e_no NUMBER) IS
SELECT emp_name, salary, grade FROM emp WHERE emp_no = e_no;
BEGIN
OPEN c1(342); FETCH c1 INTO ...;
OPEN c1(291); FETCH c1 INTO ...;
CLOSE c1;
END;
雖在同一會話,但仍需兩次開啟/擷取/關閉游標,產生多次網路往返。
方法 3:高效(單一查詢自聯結)
SELECT a.emp_name, a.salary, a.grade,
b.emp_name, b.salary, b.grade
FROM emp a, emp b
WHERE a.emp_no = 342
AND b.emp_no = 291;
單次 SQL 執行即取得所有資料,大幅減少解析與網路開銷。
在 SQL*Plus、SQL*Forms、Pro*C 中設定 ARRAYSIZE 參數(建議值 200),可增加每次擷取的資料筆數,進一步降低往返次數。
DECODE 函數可在單次掃描中完成多條件聚合,避免重複存取同一張表或重複聯結。
低效寫法(掃描兩次 EMP 表)
SELECT COUNT(*), SUM(sal) FROM emp WHERE dept_no = 20 AND ename LIKE 'SMITH%';
SELECT COUNT(*), SUM(sal) FROM emp WHERE dept_no = 30 AND ename LIKE 'SMITH%';
高效寫法(單次掃描搭配 DECODE)
SELECT COUNT(DECODE(dept_no, 20, 'X', NULL)) AS d0020_count,
COUNT(DECODE(dept_no, 30, 'X', NULL)) AS d0030_count,
SUM(DECODE(dept_no, 20, sal, NULL)) AS d0020_sal,
SUM(DECODE(dept_no, 30, sal, NULL)) AS d0030_sal
FROM emp
WHERE ename LIKE 'SMITH%';
只掃描一次 EMP 表,透過 DECODE 進行條件分組聚合,效能提升顯著。此技巧同樣適用於 GROUP BY 與 ORDER BY 子句。