DB2 優化器屬於基於成本的優化器,它依據表與索引的統計資訊來決定最佳存取路徑。雖然基本統計資訊(如資料列數、頁面數、欄位基數等)已能提供概略輪廓,但無法反映資料值的實際分布情況。當資料呈現嚴重傾斜(Skew)時,若優化器仍假設資料均勻分布,便會產生效能低落的存取計劃。分布統計資訊正是為了解決此問題而生,它包含「頻率統計」與「分位數統計」兩大類型,能精準描繪資料分布特徵,助優化器做出更精準的決策。
執行 RUNSTATS 可收集基本統計資訊,涵蓋表層面(使用頁面數、含資料列頁面數、溢位列數、資料列總數、MDC 區塊數)與欄位層面(基數、平均長度、次大/次小值、NULL 值數)等指標。然而,基本統計資訊無法回答:「特定值在欄位中出現多少次?」或「有多少列值落於某範圍內?」
以含 100 萬列的 TABLE_X 為例,查詢 SELECT * FROM TABLE_X WHERE COLUMN_Y = 'VALUE_Z'。若 COLUMN_Y 有 100 個相異值,基本統計會假設每值各佔 1 萬列。但若 'VALUE_Z' 實際佔 90 萬列(90%),優化器若採用索引掃描反而比全表掃描更慢。分布統計資訊即可揭露此類傾斜實情。
頻率統計記錄特定值的出現次數,適用於等值(=)與不等值(<>)謂詞的過濾因子估算。以下以汽車製造範例說明:
範例表 CARS:主鍵 ID,欄位 TYPE(車型 A–J),欄位 STATE(製程步驟 1–100)。表含 100 萬列,車型分布極不均勻:
TYPE COUNT A 506,135 (50.6%) B 301,985 (30.2%) C 104,105 (10.4%) D 52,492 (5.2%) E 19,584 (2.0%) F 10,123 (1.0%) G 4,876 (0.5%) H 4,589 (0.5%) I 4,403 (0.4%) J 3,727 (0.4%)
基本統計僅知 10 種車型,均假設各 10 萬列。有了頻率統計,優化器得知查詢 WHERE TYPE = 'H' 僅回傳約 4,589 列,會果斷選擇索引存取;反之查詢 TYPE = 'A' 則傾向全表掃描。
分位數統計依升序排列欄位值,按固定間隔記錄累積列數與對應值,適用於範圍謂詞(<、>、BETWEEN)的過濾因子估算。同樣以 CARS 表的 STATE 為例:
累積列數 STATE 5,479 1 54,948 10 109,990 21 159,885 31 215,050 42 265,251 52 320,167 63 370,057 73 424,872 84 475,087 94 504,298 100 ... 100 1,012,019 100
因完工車輛(STATE = 100)保留於表中,佔總量 50% 以上。優化器透過分位數統計,可精準估算 WHERE STATE < 100(進行中車輛)僅佔約 50 萬列,而 WHERE STATE BETWEEN 50 AND 70 落於中間製程區間。即使僅收集 20 個分位點,估算誤差仍可控制在 5% 以內。
使用主變數或參數標記(如 Java PreparedStatement 的 ? 佔位符)時,優化器在編譯階段無法得知實際值,故無法套用頻率統計。此時優化器退回基本統計假設均勻分布,可能導致計劃偏差。建議:
REOPT 選項(如 REOPT ONCE 或 REOPT ALWAYS),延遲優化至執行階段並代入實際參數值。RUNSTATS ... WITH DISTRIBUTION 更新分布統計,確保統計資訊與實際資料同步。RUNSTATS ON TABLE schema.tab ON KEY COLUMNS WITH DISTRIBUTION DEFAULT NUM_FREQVALUES 50(可調整保留頻率值數量)。RUNSTATS ON TABLE schema.tab ON KEY COLUMNS WITH DISTRIBUTION DEFAULT NUM_QUANTILES 20(預設 20 通常足夠)。EXPLAIN)與實際執行時間。總結而言,分布統計資訊是 DB2 優化器從「盲目假設均勻」邁向「精準感知分布」的關鍵鑰匙。DBA 與開發人員應共同理解其原理、收集時機與應用限制,才能在資料傾斜普遍存在的實務環境中,持續榨取最佳查詢效能。