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

深入解析 DB2 優化器中的分布統計信息應用

     編輯:DB2 教學

前言

在 DB2 資料庫中,優化器負責為 SQL 查詢或 DML 語句(INSERT、UPDATE、DELETE)生成訪問計劃。訪問計劃決定了表的訪問順序、索引選擇以及連接方法,其優劣直接影響 SQL 執行效率。DB2 採用基於成本的優化器,依據表與索引的統計信息做出決策。除了基本統計信息外,DB2 還支援收集分布統計信息,這對於處理數據傾斜、重複值高的場景至關重要。本文將詳細闡述分布統計信息的類型、收集方式、優化器如何利用它們,以及參數標記對其效能的影響。

基本統計信息與分布統計信息的差異

執行 RUNSTATS 可收集基本統計信息,包括:表的頁面數、行數(基數)、溢出行數;列的基數、平均長度、最大/最小值、NULL 值個數等。優化器據此假設數據均勻分布。然而現實中,數據往往存在熱點值或聚集現象。例如某表有 100 萬行,某列只有 10 個不同值,基本統計會估算每值 10 萬行,但實際可能某值佔 90%。此時優化器可能選錯索引,導致計劃次優。分布統計信息正是為了解決此問題而生。

分布統計信息的兩大類型

頻率統計信息

記錄列中出現頻率最高的 N 個值及其出現次數。適用於等值(=)或不等值(<>)謂詞的過濾因子估算。例如 WHERE TYPE = 'A',優化器可精確得知 'A' 的真實選擇率,從而決定是否使用索引掃描。

分位數統計信息

將列值按升序排列,按固定行間隔採樣,記錄對應值及小於等於該值的行數。適用於範圍謂詞(<、>、<=、>=、BETWEEN)的過濾因子估算。例如 WHERE STATE < 100,優化器能估算出滿足條件的行數比例。預設收集 20 個分位數,估算誤差通常低於 5%。

實戰案例:分布統計信息帶來的性能提升

以 CARS 表為例,100 萬行,99.9% 汽車已完工(STATE=100),僅 1000 輛在製造中。查詢:SELECT * FROM CARS WHERE STATE < 100 AND TYPE = 'A'。

無分布統計時

優化器誤判 STATE 均勻分布,選擇 I_TYPE 索引,掃描約 10 萬 RID,實際讀取 99,336 行,耗時 0.53 秒。

有分布統計時

優化器識別 STATE < 100 過濾性極高,改用 I_STATE 索引,僅讀取 1,000 行,耗時 0.014 秒,性能提升 36 倍。

分布統計信息的收集與管理

使用 RUNSTATS ... WITH DISTRIBUTION 收集。為控制開銷,建議僅對有需求的列收集:

  • RUNSTATS ON TABLE SAMPLE.CARS WITH DISTRIBUTION ON COLUMNS (TYPE, STATE) AND INDEXES ALL
  • 可指定 NUM_FREQVALUES(預設 10)和 NUM_QUANTILES(預設 20)

查詢 SYSCAT.COLDIST 視圖可驗證是否已收集。重新執行無 WITH DISTRIBUTION 的 RUNSTATS 會清除分布統計。

參數標記與主變量的限制

JDBC PreparedStatement 使用參數標記(?)可避免重複編譯,但優化器在編譯階段看不到具體值,無法充分利用頻率統計信息。實測顯示:使用參數標記時,雖優於無統計信息,但較具體值+分布統計仍慢 8 倍。建議:高頻簡單語句用 PreparedStatement;複雜報表查詢優先用具體值(Statement 或動態 SQL),讓優化器發揮最大效能。

總結

分布統計信息是優化器應對數據傾斜的關鍵武器。DBA 應識別熱點列、非常勻分布列,定期收集頻率與分位數統計;開發人員需權衡 PreparedStatement 的編譯復用優勢與優化器精準估算的需求,根據業務場景選擇最佳實踐。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved