對業務熟悉度直接決定倉庫性能上限。不懂業務的 DBA,縱使技術深厚,也難設計出最優系統。
規範化減少冗余、縮窄行寬、加速全表掃描;但多表連接帶來高 CPU/I/O 開銷。實戰策略:在邏輯有效性前提下,適度冗余高頻查詢所需列,用空間換時間。
案例: 訂單明細表 OrderDetail 原需連接投遞員、收款員、物品、價格策略、客戶 5 張表。百萬級數據下連接查詢耗時數小時。將高頻屬性(如物品名、客戶名、單價)直接冗余入 OrderDetail,查詢效率指數級提升。
在滿足業務前提下選擇高效類型:
BLOB 存指針/引用,實體文件外置,減輕數據庫存儲與 I/O。UDT (User Defined Datatypes) 封裝業務語義。索引加速查詢但拖慢寫入、佔磁盤、需維護。合理使用原則:
GROUP BY/ORDER BY 的列建索引,利用索引有序性避免排序。利用索引順序避免顯式排序。以下場景排序不可省略:索引缺失排序列、GROUP BY/ORDER BY 列序與索引不一致、跨表排序。對策:補充索引、合併表(適度反範式)、縮小排序列範圍。
整型主鍵極大優於字符型。 字符比較開銷遠大於整型,數據量大時微小差異放大為明顯響應差距。
嵌套子查詢對外層每行掃描內層表,效率極低。改寫為連接 可大幅降低掃描代價。
-- 子查詢:外層掃描 82%,內層 16%
SELECT CreateUser FROM Order
WHERE OrderNo IN (SELECT OrderNo FROM OrderDetail WHERE Price=0.5);
-- 連接查詢:外層 74%,內層 14%
SELECT CreateUser FROM Order, OrderDetail
WHERE Order.OrderNo = OrderDetail.OrderNo AND Price=0.5;
原則:能連接不子查詢;必須子查詢時,內層盡可能過濾更多行。
LIKE 'M___' 即使有索引也會全表掃描。改用範圍查詢 CreateUser > 'M' AND CreateUser < 'N' 走索引,速度飛躍。
DISTINCT 產生工作表並排序去重,大增 I/O。能用唯一約束/業務邏輯保證唯一時,避免使用。
!=、<>、NOT IN 導致全表掃描。改用正向邏輯或 NOT EXISTS(配合索引)替代。
臨時表落盤,磁盤 I/O 遠慢於內存。分布式環境下還引入同步問題。復雜查詢優先考慮 WITH 子查詢(CTE)或物化視圖,避免臨時表。
SP 首次執行生成優化計劃並緩存,後續調用跳過優化編譯,顯著降低延遲。Stored Procedure Builder 支持開發測試全流程。
DB2 支持表空間、表、列、索引多粒度鎖。粒度大→開銷小、並發低;粒度小→開銷大、並發高。大型系統禁用表級鎖(長查詢阻塞全系統)。解法:利用視圖隔離直接表操作,兼顧並發與性能。
性能優化是系統工程:設計階段奠基(業務理解、範式權衡、分區、類型、索引)、查詢層精煉(排序、主鍵、連接、通配符、DISTINCT、負邏輯、臨時表、SP)、運行期監控調優(工具輔助、鎖粒度控制)。無銀彈,唯有在具體業務場景中不斷度量、權衡、迭代。