資料庫調優無銀彈,同一招在系統 A 靈驗、系統 B 失效。但遵循核心原則能顯著降低踩坑機率。本文歸納 7 個跨平台 (Oracle/SQL Server/DB2/MySQL/Sybase) 通用法寶。
場景:將訂單超 10 萬標記為「Preferred」。
反模式: UPDATE customer SET rank='Preferred' WHERE order_amt > 100000; — 產生 Redo/Undo,每行寫兩次。
正解: 查詢中內嵌 CASE WHEN order_amt > 100000 THEN 'Preferred' ELSE rank END,僅滿足條件行產生寫入,效能提升數量級。
直接複製他人查詢常導致:多餘 Join、缺少 Where 條件、返回超集。原則: 重用前務必審視 Select List、Join 條件、Where 子句,補上業務必要過濾,砍掉無關 Join。
SELECT * 是效能殺手:網路傳輸暴增、緩衝區污染、解析開銷大。實例:120 欄位、百萬行表,只需 3~5 欄位卻全撈。鐵律: 顯式列出欄位,拒絕 *。
反模式:同一存儲過程中,先查「加州客戶」存臨時表 #1,再查「收入>4萬」存臨時表 #2,最後 Join 兩張臨時表 — **大表掃了兩遍**。
正解:單一查詢 WHERE state='CA' AND income>40000。
進階:若多步驟需同一大表子集,首次查詢物質化 (建立臨時表/物化視圖/Global Temporary Table),後續步驟複用。
場景:大表 Join 大表且帶複雜過濾。
策略:先將大表過濾後的關鍵欄位導入臨時表 (含索引),再用臨時表 Join。
優勢:縮小 Join 輸入規模、避免重複掃描大表、統計資訊更精準 (臨時表可重新收集統計)。
高頻報表對大表 Join 聚合,若容許分鐘級延遲:
1. 排程任務預先聚合寫入摘要表。
2. 報表直接查摘要表,秒級返回。
比 View 更強:View 每次跑都掃大表;摘要表僅排程跑一次。適用「同報表 10 分鐘內重複跑」等高併發場景。
單一大事務刪百萬行:
- 殺進程需回滾整個事務,耗時極長。
- 長鎖導致阻塞、死鎖風險。
- Redo/Undo 爆漲。
分批模板:
LOOP
DELETE FROM big_table WHERE condition AND ROWNUM <= 10000;
EXIT WHEN SQL%ROWCOUNT = 0;
COMMIT;
END LOOP;
優勢:回滾段壓力小、鎖持有時間短、I/O 平滑、併發友好。**務必選業務低峰期執行。**
7 大法寶非孤立使用,需根據具體負載組合。核心心法:**開發階段即思考生產負載,主動規避全表掃描、大事務、過度投影、重複掃描**。DBA 會感謝你,用戶更會感謝你。