-- 1. 以非空判斷替代 (需業務允許)
col IS NOT NULL → col > 0 或 col > ''
-- 2. 設計階段:NOT NULL + DEFAULT
ALTER TABLE t MODIFY status DEFAULT 'NEW' NOT NULL;
-- 3. 函數索引 (11g+)
CREATE INDEX idx_t_status_nvl ON t (NVL(status, 'NULL_MARK'));
WHERE NVL(status, 'NULL_MARK') = 'NULL_MARK'
-- 4. 位圖索引 (低基數、DW)
CREATE BITMAP INDEX idx_t_status_bmp ON t (status);
LIKE '%abc%':全表掃描,不可避免 (除 Oracle Text)。LIKE 'abc%':索引範圍掃描 (Index Range Scan)。YY_BH LIKE '%5400%' → 改寫為 YY_BH LIKE 'X5400%' OR YY_BH LIKE 'B5400%' 走索引兩次範圍掃描。-- 失效
WHERE col1 || col2 = 'value'
-- 優化:拆分條件
WHERE col1 = 'val1' AND col2 = 'val2'
-- 或使用虛擬欄位 + 索引 (11g+)
ALTER TABLE t ADD (col12 AS (col1 || col2) VIRTUAL);
CREATE INDEX idx_t_col12 ON t (col12);
| 失效模式 | 優化改寫 |
|---|---|
| WHERE SUBSTR(hbs_bh,1,4) = '5400' | WHERE hbs_bh LIKE '5400%' |
| WHERE TRUNC(sk_rq) = TRUNC(SYSDATE) | WHERE sk_rq >= TRUNC(SYSDATE) AND sk_rq < TRUNC(SYSDATE)+1 |
| WHERE ss_df + 20 > 50 | WHERE ss_df > 30 |
| WHERE 'X' || hbs_bh > 'X5400021452' | WHERE hbs_bh > '5400021542' |
| WHERE sk_rq + 5 = SYSDATE | WHERE sk_rq = SYSDATE - 5 |
| WHERE hbs_bh = 5401002554 (隱式 TO_NUMBER) | WHERE hbs_bh = '5401002554' (字串比較) |
| WHERE ys_df > cx_df (多欄運算) | 無法優化,考慮虛擬欄位或物化視圖 |
| WHERE qc_bh || kh_bh = '5400250000' | WHERE qc_bh = '5400' AND kh_bh = '250000' |
NOT 或 <>NOT IN 子查詢LIKE '%...'IS NULL / IS NOT NULL (單欄 B-Tree)-- 業務確認無重複 (如當前表/歷史表、分區表)
SELECT * FROM gc_dfys UNION ALL SELECT * FROM ls_jg_dfys;
-- 禁用 UNION 除非確需去重
Oracle 對 完全相同字元串 (含大小寫、空格、換行、Schema 前綴) 才共享游標。
-- 這 4 句會產生 4 個 Parent Cursor,佔用 4 倍 Shared Pool
SELECT * FROM zl_yhjbqk;
SELECT * FROM zl_yhjbqk ;
SELECT * FROM DLYX.ZL_YHJBQK;
select * from zl_yhjbqk;
-- 規範:統一大寫、統一 Schema 前綴、統一格式化
SELECT * FROM DLYX.ZL_YHJBQK;
-- 低效:99% 條件優先,大量無效比較
SELECT * FROM t WHERE dy_dj = '1KV以下' AND xh_bz = 1;
-- 高效:0.5% 條件優先,早期過濾
SELECT * FROM t WHERE xh_bz = 1 AND dy_dj = '1KV以下';
現代 CBO (10g+) 會自動根據統計資訊重排,但良好習慣仍有助穩定計畫。
ORDER BY 非索引欄 → 建立索引或接受 Sort 開銷;嚴禁 ORDER BY expression。t1.col,減少解析時間。NVL, COALESCE, CASE, DECODE, REGEXP_SUBSTR 替代複雜 PL/SQL。