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

Oracle SQL 效能調優實戰:從表連接順序到 WHERE 條件優化

     編輯:Oracle 資料庫基礎

核心觀念:RBO 下的執行順序決定論

在規則基礎優化器(RBO)模式下,Oracle 解析器遵循「從右到左」處理 FROM 子句表名,「自下而上」解析 WHERE 子句條件。掌握這兩大鐵律,是編寫高效 SQL 的基石。

1. 表連接順序:小表驅動大表

原則:FROM 子句最右側表(Driving Table)最先被掃描並排序,故應將記錄數最少的表放在最後。

-- TAB1: 16,384 筆 | TAB2: 1 筆
-- 最佳:小表在右
SELECT COUNT(*) FROM tab1, tab2;  -- 0.96 秒
-- 差勁:大表在右
SELECT COUNT(*) FROM tab2, tab1;  -- 26.09 秒

三表以上連接時,選擇交叉表(Intersection Table)作為驅動表——即被其他表引用最多的表(如 EMP 連接 LOCATION、CATEGORY)。

2. WHERE 條件排序:過濾力強的條件後置

Oracle 由下往上解析 WHERE 條件,因此:

  • 表連接條件(JOIN)寫在最前
  • 過濾比例最高(過濾力最強)的條件寫在最後
-- 低效:先過濾 SAL > 50000,再跑子查詢
SELECT ... FROM emp e
WHERE sal > 50000
  AND job = 'MANAGER'
  AND 25 < (SELECT COUNT(*) FROM emp WHERE mgr = e.empno);  -- 156.3 秒

-- 高效:先跑子查詢過濾 99% 資料,再檢查薪資職稱
SELECT ... FROM emp e
WHERE 25 < (SELECT COUNT(*) FROM emp WHERE mgr = e.empno)
  AND sal > 50000
  AND job = 'MANAGER';  -- 10.6 秒

3. 禁用 SELECT *:明確列出欄位

SELECT * 強制 Oracle 查詢資料字典轉換欄位名,增加解析開銷。生產環境務必明確列出所需欄位,亦利於應用層與資料庫解耦。

4. 減少資料庫往返:批次化操作

每次 SQL 執行涉及解析、綁定、執行、獲取等多輪網路交互。將多次查詢合併為單次多表連接或 IN 列表,可大幅降低開銷。

-- 方法 1:兩次往返(最差)
SELECT ... FROM emp WHERE emp_no = 342;
SELECT ... FROM emp WHERE emp_no = 291;

-- 方法 2:游標循環(次差)
-- PL/SQL 迴圈仍需多次 FETCH

-- 方法 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*Plus / Pro*C 中設定 ARRAYSIZE 200,單次獲取更多行,減少網路交互。

總結

RBO 時代的優化邏輯雖在 CBO(成本優化器)主導的現代版本中部分失效,但「小表驅動大表、強過濾後置、減少往返」的思想仍具普世指導意義,值得內化為肌肉記憶。

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