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

Oracle SQL 調優實戰大全:操作符改寫、條件下推、HINT 指導、寫法規範與執行計畫分析

     編輯:Oracle 資料庫基礎

操作符改寫:從「寫得快」到「跑得快」

操作符/模式問題改寫方案原理
IN 子查詢轉換為 JOIN 失敗時先執行子查詢,多一次轉換開銷改用 EXISTS / JOIN半連接 (SEMI JOIN) 可提前過濾,避免物化子查詢
NOT IN**含 NULL 時結果為空**,且無法使用索引NOT EXISTS / LEFT JOIN ... IS NULL反連接 (ANTI JOIN) 可走索引,語義正確
!= / <> 永遠不走索引,全表掃描`a > 0 OR a < 0` / `a > ''` (字串)將「不等於」拆解為「範圍」讓索引生效
IS NULL / IS NOT NULLB-Tree 不存 NULL,無法走索引預設值 + CHECK 約束 / Function-Based Index / Bitmap Index將 NULL 轉為實際值或用 Bitmap 索引 NULL
LIKE '%abc%'前導通配符導致全表掃描LIKE 'abc%' / Oracle Text / 反向鍵索引前導固定前綴可走索引範圍掃描
UNION去重排序開銷大UNION ALL (業務確無重複時)省略 SORT UNIQUE 操作
>= vs > 常數`A >= 3` 直接定位 3;`A > 2` 先定位 2 再過濾優先用 >= / <= 邊界值減少索引掃描起始點比較次數

條件寫法阻礙索引的典型模式與修正

阻礙模式範例修正原則
函數包裹列`SUBSTR(hbs_bh,1,4)='5400'``hbs_bh LIKE '5400%'`列保持「裸露」,函數移至常數側
隱式/顯式運算`TRUNC(sk_rq)=TRUNC(SYSDATE)``sk_rq >= TRUNC(SYSDATE) AND sk_rq < TRUNC(SYSDATE)+1`範圍查詢保留索引
列參與運算`ss_df+20 > 50``ss_df > 30`常數預計算移至右側
字串拼接比較`'X'||hbs_bh > 'X5400021452'``hbs_bh > '5400021542'`避免列側運算
隱式類型轉換`hbs_bh = 5401002554` (hbs_bh 是 VARCHAR2)`hbs_bh = '5401002554'`顯式轉換常數,避免列側 TO_NUMBER
多列運算`ys_df > cx_df`無法直接優化,考慮虛擬欄位 + 索引列間運算破壞索引
多列拼接比較`qc_bh||kh_bh = '5400250000'``qc_bh='5400' AND kh_bh='250000'`拆解為多列等值,利用組合索引

SQL 寫法規範:共享游標與解析復用

  • **大小寫一致、空格一致、表前綴一致** → 同一 SQL 文本 → 僅硬解析一次,Shared Pool 僅存一份計畫,統計頻率準確。
  • 建立編碼規範:關鍵字大寫、表別名統一、縮進統一、綁定變數命名規範。

WHERE 條件順序與表連接順序對 CBO 的影響

  • **無索引/無統計資訊時**:Oracle 按 FROM 後表順序、WHERE 後條件順序執行,小表驅動大表、高選擇度條件前置可大幅降低 CPU。
  • **有統計資訊時**:CBO 自動估算成本選擇最優順序,**但統計過期/缺失會退化為規則模式**,此時寫法順序直接生效。
  • **最佳實踐**:`WHERE` 先寫高選擇度 (過濾率高) 條件;`FROM` 先寫小表/驅動表。

HINT 指導:最後手段,慎用

核心原則:HINT 僅是建議,CBO 可能忽略。**優先修正統計資訊、索引設計、SQL 改寫**,HINT 僅作臨時戰術手段或計畫固化 (`SQL Plan Baseline`)。

結語

SQL 調優是 **「改寫操作符 → 條件列裸露 → 統計資訊準確 → 索引匹配 → 寫法規範 → HINT 兜底」** 的系統工程。建立「高頻 SQL 審核清單」,將上述規則內化為團隊編碼規範,從源頭杜絕低效 SQL 入庫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
分類常用 HINT場景
目標模式ALL_ROWS / FIRST_ROWS(n) / CHOOSE全量報表 vs 分頁查詢首屏
連接方法USE_NL / USE_HASH / USE_MERGE小驅動大 NL、大大表 Hash、排序合併 Merge
索引指定INDEX(t idx_name) / NO_INDEX(t idx_name)CBO 選錯索引時強制/禁止
並行執行PARALLEL(t 4) / NO_PARALLEL大表全掃描並行化
動態採樣DYNAMIC_SAMPLING(t 4)統計缺失臨時補齊