首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

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

     編輯:Oracle 資料庫基礎

4. 選擇最有效率的表名順序 (僅 RBO 有效)

RBO 解析 `FROM` 子句遵循從右到左順序,最後寫入的表 (Driving Table) 最先被處理。策略:選擇列數最少的表作為 Driving Table。

-- TAB1 16,384 列,TAB2 1 列
SELECT COUNT(*) FROM TAB1, TAB2;  -- 0.96 秒 (TAB2 為 Driving Table,佳)
SELECT COUNT(*) FROM TAB2, TAB1;  -- 26.09 秒 (TAB1 為 Driving Table,差)

三表以上連接:選擇交叉表 (被其他表引用的表) 作為 Driving Table。
範例:`EMP` 連接 `LOCATION`、`CATEGORY`,`EMP` 為交叉表,應置於 `FROM` 最後。

5. WHERE 子句中的連接順序

Oracle 自下而上解析 WHERE 條件。原則:

  • 表連接條件 (Join Conditions) 寫在最前面。
  • 過濾性最強 (過濾掉最多列) 的條件寫在最後面 (最晚評估)。
-- 低效:先評估高選擇性條件,再做子查詢
SELECT ... FROM EMP E
WHERE SAL > 50000
AND JOB = 'MANAGER'
AND 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO);  -- 156.3 秒

-- 高效:先評估相關子查詢 (最耗資源),最後簡單過濾
SELECT ... FROM EMP E
WHERE 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO)
AND SAL > 50000
AND JOB = 'MANAGER';  -- 10.6 秒

注意:CBO 會自動重排序條件評估順序,此規則主要針對 RBO 或輔助 CBO 穩定計畫。

6. SELECT 子句中避免使用 `*`

  • `SELECT *` 解析階段需查詢 Data Dictionary 將 `*` 展開為所有欄位名,增加 Parse 時間與 Library Cache 壓力。
  • 網路傳輸不必要欄位,增加延遲與頻寬佔用。
  • 應用程式依賴欄位順序/數量,`ALTER TABLE ADD COLUMN` 導致程式中斷。
  • 最佳實踐:明確列出所需欄位 `SELECT EMPNO, ENAME, SAL ...`。

7. 減少資料庫存取次數

每次 SQL 執行伴隨 Parse、Bind、Execute、Fetch 多次往返。合併請求可大幅降低開銷。

範例:查詢兩個員工資料

-- 方法 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 迴圈游標,仍多次 Execute/Fetch (次差)
DECLARE CURSOR C1 (E_NO NUMBER) IS SELECT ... FROM EMP WHERE EMP_NO = E_NO;
BEGIN OPEN C1(342); FETCH ...; OPEN C1(291); FETCH ...; END;

-- 方法 3:單一 SQL 自連接 (最佳)
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;

調優參數:ARRAYSIZE

  • SQL*Plus / SQL*Forms / Pro*C / OCI / JDBC 皆支援設定 Fetch Array Size。
  • 預設通常 15-50,建議設為 200 (或更大視記憶體)。
  • 效果:每次網路往返傳回更多列,減少 Round-trip,大幅提升大量資料提取速度。

本章小結

掌握 RBO 連接順序、WHERE 條件排序邏輯、拒絕 `SELECT *`、合併多次查詢為單一 SQL 並調大 `ARRAYSIZE`,是應用層面最直接、投資報酬率最高的調優手法。下一章將探討 `EXISTS` vs `IN`、子查詢轉連接、臨時表應用等進階重寫技巧。

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