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

Oracle SQL 效能調優系列 (二):表連接順序、WHERE 條件排序、避免 SELECT *、減少資料庫往返

     編輯:Oracle 資料庫相關知識

4. 選擇最有效率的表連接順序 (RBO 環境)

RBO 依 FROM 子句**從右往左**解析,最後寫的表 (Driving Table) 優先存取。原則:**小表驅動大表**。

-- TAB1: 16,384 列, TAB2: 1 列
SELECT COUNT(*) FROM tab1, tab2;   -- 0.96 秒 (TAB2 驅動)
SELECT COUNT(*) FROM tab2, tab1;   -- 26.09 秒 (TAB1 驅動)

三表以上:選擇 **Intersection Table** (被其他表參考的表) 作為驅動表。

5. WHERE 子句條件排序 (RBO)

RBO **自下而上**解析 WHERE 條件:

  • **表連接條件**寫在最前 (最下方)
  • **過濾性最強** (過濾掉最多列) 的條件寫在最後 (最上方)
-- 低效 (156 秒)
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';

6. 避免 SELECT *

  • 解析階段需查詢 Data Dictionary 展開所有欄位,增加開銷
  • 網路傳輸不必要欄位
  • 阻礙 Covering Index 最佳化
  • 表結構變更導致應用程式錯誤

最佳實務: 明確列出所需欄位。

7. 減少資料庫往返次數

每次 SQL 執行皆涉及:解析、綁定、執行計畫、Fetch、網路往返。

方法描述效率
多條獨立 SQL分開查詢 empno=342、empno=291最低
PL/SQL Cursor 迴圈OPEN/FETCH/CLOSE 多次中等
單一 SQL 多表自連接SELECT a.*, b.* FROM emp a, emp b WHERE a.empno=342 AND b.empno=291最高

額外調優參數

  • ARRAYSIZE (SQL*Plus/Forms/Pro*C):預設 15,建議設 100~200,減少 Fetch 往返
  • SET AUTOTRACE TRACEONLY EXPLAIN:快速查看執行計畫
  • EXPLAIN PLAN + DBMS_XPLAN.DISPLAY:詳細分析

RBO vs CBO 適用提醒

上述規則 4、5 僅在 **Rule-Based Optimizer (RBO)** 下有效。現代 Oracle (10g+) 預設 **Cost-Based Optimizer (CBO)**,依統計資訊自動決定連接順序與條件評估順序,**無需手工調整 SQL 寫法順序**。重點應放在:

  1. 收集完整、準確的統計資訊 (DBMS_STATS)
  2. 建立適當索引、直方圖、擴展統計
  3. 使用綁定變數、避免隱含轉換
  4. 必要時用 Hint (LEADING, ORDERED) 引導
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved