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

Oracle SQL 效能優化 34 條鐵律:從寫法到索引的完整指南

     編輯:Oracle 資料庫基礎

查詢結構優化

  1. 表順序(RBO):FROM 右至左解析,記錄最少的表放最後(做驅動表)。三表以上找交叉表。
  2. WHERE 條件順序:自下而上解析,表連接寫最前,過濾性最強條件寫最後。
  3. 避免 SELECT *:轉換欄位名需查資料字典,增解析開銷。
  4. 減少資料庫往返:批次處理、陣列提取(ARRAYSIZE 200)。
  5. DECODE/CASE 避免重複掃描:單次掃描完成多條件分支。
  6. 合併無關查詢:多條簡單查詢合為一條,減少解析與網路開銷。

DML 優化

  1. 刪除重複用 ROWID:
    DELETE FROM emp e
    WHERE e.rowid > (SELECT MIN(x.rowid) FROM emp x WHERE x.emp_no = e.emp_no);
  2. TRUNCATE 替代 DELETE:不產生 UNDO、不觸發 Trigger、高水位歸零(DDL,不可回滾)。
  3. 頻繁 COMMIT:釋放 UNDO、鎖、Redo Log Buffer、管理開銷。

條件改寫

  1. WHERE 替代 HAVING:HAVING 在分組後過濾,WHERE 在分組前過濾,減少排序聚合開銷。
  2. 減少子查詢掃表:改用 JOIN 或 WITH 子句。
  3. EXISTS 替代 IN、NOT EXISTS 替代 NOT IN:後者觸發子查詢全表掃描+排序合併。
  4. EXISTS 替代 DISTINCT:一對多查詢去重,EXISTS 滿足即返回,避免排序。

索引使用鐵律

  1. 別名 + 前綴欄位:減少解析時間、避免歧義。
  2. 避免索引列上用 NOT、函數、運算:均導致全表掃描。
    • ❌ sal * 12 > 25000 → ✅ sal > 25000/12
    • ❌ WHERE dept_code IS NOT NULL → ✅ WHERE dept_code >= 0
  3. >= 替代 >:直接定位首滿足行,避免掃描邊界值。
  4. UNION 替代 OR(索引列):OR 導致全掃,UNION 可分別走索引再合併。
  5. IN 替代 多個 OR:可讀性與效能兼顧(8i 後優化器對等)。
  6. 複合索引必須引用導欄:否則索引失效。
  7. UNION ALL 替代 UNION:免排序,但需業務允許重複。
  8. WHERE 替代 ORDER BY:ORDER BY 需嚴格符合索引順序且非空才走索引。
  9. 隱式類型轉換殺索引:char_col = 123 會轉 TO_NUMBER(char_col) 導致失效,寫 char_col = '123'。

殺手級 WHERE 陷阱

  • !=、||、+、同索引列互相比較 → 全表掃描。

統計與存取路徑

  1. 存取超過 30% 資料 → 全表掃描更優。
  2. 索引未必比全掃快(同數量級),但通常快數倍至數千倍。
  3. DISTINCT/UNION/MINUS/INTERSECT/ORDER BY 觸發 SORT,調大 SORT_AREA_SIZE。
  4. GROUP BY 前先 WHERE 過濾,大幅減少分組資料量。

自動發現低效 SQL

SELECT executions, disk_reads, buffer_gets,
       ROUND((buffer_gets-disk_reads)/buffer_gets,2) hit_ratio,
       ROUND(disk_reads/executions,2) reads_per_run,
       sql_text
FROM   v$sqlarea
WHERE  executions > 0
AND    buffer_gets > 0
AND    (buffer_gets-disk_reads)/buffer_gets < 0.8
ORDER  BY 4 DESC;

索引維護

定期 ALTER INDEX idx REBUILD [TABLESPACE ts] 消除碎片、恢復聚簇因子。

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