Upgrade to Pro — share decks privately, control downloads, hide ads and more …

【データベース】統計情報と単一カラムのヒストグラム

Avatar for シノラー シノラー
March 19, 2025
7

 【データベース】統計情報と単一カラムのヒストグラム

Avatar for シノラー

シノラー

March 19, 2025
Tweet

More Decks by シノラー

Transcript

  1. 目次 1. ヒストグラムとは? 2. 統計情報のヒストグラムとは? 3. 統計情報のヒストグラムの種類 4. RDBMSごとのヒストグラム仕様の比較 5.

    各ヒストグラムの活用例(クエリ最適化) 6. 検証の準備:ヒストグラムの確認方法 7. 検証:ヒストグラムによるクエリ最適化の影響 8. まとめ
  2. 1. ヒストグラムとは? • 棒グラフとヒストグラムの違い 比較項目 棒グラフ ヒストグラム 目的 カテゴリごとの比較 データの分布を表現 X軸

    独立したカテゴリ (商品A, B, C) 連続した値の範囲 (0-10, 10-20, 20-30) バーの間隔 あり(区別が明確) なし(範囲が連続) データの種類 定性的データ(カテゴリ) 定量的データ(数値) 例 「テストの点数比較」 「テストの点数分布」
  3. 2. 統計情報のヒストグラムとは? • データベースがクエリ最適化のために持つ統計情報の一種 • カラム内のデータの分布 を記録し、実行計画の精度を向上 させる • WHERE句のフィルタリングや結合処理 で、

    適切なインデックスや結合方式を選択するために活用 • ヒストグラムがないと、データ分布を誤認し、 非効率なクエリプランが選ばれる可能性あり • RDBMSごとに異なるヒストグラムの実装が存在
  4. 3. 統計情報のヒストグラムの種類 • 等間隔ヒストグラム (Equal-Width Histogram) ◦ 各ビンの幅が均一(例:0-10, 10-20, 20-30…) ◦

    シンプルで計算コストが低い ◦ データが均等に分布している場合に適している • 等深度ヒストグラム (Equal-Height Histogram) ◦ 各ビンに同じ数のデータを含める(ビンの幅は可変) ◦ データが偏っていても、分布の特徴を反映しやすい ◦ 値の偏りが大きいデータに適している • ハイブリッドヒストグラム (Hybrid Histogram) ◦ 等間隔+等深度の組み合わせ ◦ データベース製品ごとに最適化された手法(製品によってルールが異なる) ◦ 特定の値が頻出するデータに適している • ✅ 統計情報のヒストグラムは、データの分布を適切に表現するために種類が選ばれる!
  5. 3. 統計情報のヒストグラムの種類 • ハイブリッドヒストグラム (イメージはPostgreSQLの等深度+MCV) 📌 「高頻度の値」は個別のビンに分ける( MCVの考 え方)  →「特定の値(例:31)は個別のビンとして扱い、他 の値は統合」

    📌 「その他の値」は等深度で分割  →「データ数を均等にするように、範囲ごとにグ ループ化!」 📌 ビンの幅は可変!データの偏りに応じて調整さ れる  →「等間隔ではなく、データの分布によって区切り が変わるよ!」 📌 ヒストグラム+MCVのハイブリッド手法!  →「ヒストグラムの精度を上げるため、頻出値を個 別に記録する仕組み!」 ✅ 「データの偏りを考慮し、実行計画をより最適 化!」 判断基準はDBが決め るためざっくり理解で OK
  6. 4. RDBMSごとのヒストグラム仕様の比較 RDBMS 等間隔 等深度 その他 Oracle ❌ なし ✅ あり

    ハイブリッド(等深度 + MCV) PostgreSQL ❌ なし ✅ あり ハイブリッド(等深度 + MCV) ※Oracleとは相違点あり MySQL ❌ なし ✅ あり シングルトンヒストグラム
  7. 5. 各ヒストグラムの活用例(クエリ最適化) • 等間隔ヒストグラム → データが均等に分布する場合に適切。シンプルな実行計画で処理 ✅ 活用例:ログデータのタイムスタンプ集計(均等な間隔でデータが存在) • 等深度ヒストグラム → データの密度に応じて範囲を調整。偏ったデータでも適切な実行計画に。 ✅

    活用例:売上データ(特定の価格帯に集中している場合の最適化) • ハイブリッドヒストグラム(等深度 + MCV) → 頻出値(MCV)を個別管理し、その他のデータは等深度でカバー。 ✅ 活用例:アクセスログ解析(特定のIPが大量に記録される場合のフィルタリング)
  8. 6. 検証の準備:ヒストグラムの確認方法 • テーブル構造 & データの分布 カラム名 データの分布 検証の目的 pg_stats 情報

    COL_A 一意なデータ (1〜400万) 主キー検索で Index Scan になるか? MCVなし / ヒストグラムあり COL_B 100000 が 40% を占める MCV の影響で Seq Scan になるか? MCVあり / ヒストグラムあり COL_C 10000(50%) & 90000(50%) 2種類の場合、MCVの影響はどうか? MCVあり / ヒストグラムなし COL_D A〜J の 10 種類(均等) カテゴリデータ(10種類)で MCVの影響はどうか? MCVあり / ヒストグラムなし
  9. 6. 検証の準備:ヒストグラムの確認方法 • pg_stats のデータ カラム名 n_distinct most_common_vals(MCV) histogram_bounds correlation COL_A

    -1 (ユニーク) NULL {112, 38992…} (多いため略) 0.83 COL_B 31803 {100000} (39.95%) {10005, 10899…} (多いため略) -0.65 COL_C 2 {10000, 90000} (約50%ずつ) NULL 1.0 COL_D 10 {E, G, B, F, H, C, A, I, J, D} (約10%ずつ) NULL 0.108 ユニーク な値の数 よく出る値リスト (NULLはMCVを使用しない) 等深度ヒストグラムの境界 (NULLは等深度を使用しない ) カラム値の並びと物理順の相関 1 に近い:IndexScan向き -1に近い:逆IndexScan向き 0 に近い:FullScanの可能性 「物理順」  →ディスク上のデータの並び   (実際の保存順) 「カラム値の順序」  →カラムの値を大小順に並べた場合の 論理的な概念(物理順とは関係なし)
  10. 6. 検証の準備:ヒストグラムの確認方法 • 検証用のクエリ クエリ 意味 SELECT * FROM A WHERE

    COL_A = 100000; 主キー検索で Index Scan になるか? SELECT * FROM A WHERE COL_B = 100000; MCV の影響で Seq Scan になるか? SELECT * FROM A WHERE COL_B = 50000; 低頻度値で Index Scan になるか? SELECT * FROM A WHERE COL_C = 10000; 二つの山がある分布(バイモーダル分布) はスキャンに影響するか? SELECT * FROM A WHERE COL_C = 90000; 同上 SELECT * FROM A WHERE COL_D = 'A'; カテゴリ型データで Bitmap Index Scan になるか?
  11. 7. 検証:ヒストグラムによるクエリ最適化の影響 • 検証結果 クエリ スキャン方法 COL_A = 100000; Index Scan

    COL_B = 100000; Seq Scan COL_B = 50000; Index Scan COL_C = 10000; Index Scan COL_C = 90000; Index Scan COL_D = 'A'; Bitmap Index Scan
  12. 7. 検証:ヒストグラムによるクエリ最適化の影響 ✅ 結果からの考察(1 / 2) • COL_B = 100000 は

    Seq Scan になった ◦ 40% のデータを取得するため、Index Scan より Seq Scan が効率的 ◦ correlation = 0 に近いため、Index Scan ではランダムアクセスが発生し、 Seq Scan の方が適切と判断された可能性が高い。 ◦ もし correlation = 1.0 または -1.0 に近ければ、Index Scan が選ばれた可能 性がある。 • COL_B = 50000 は Index Scan になった ◦ MCV に登録されていないため、PostgreSQL はヒストグラムを参照 ◦ 低頻度値なので Index Scan を選択
  13. 7. 検証:ヒストグラムによるクエリ最適化の影響 ✅ 結果からの考察(2 / 2) • COL_C = 10000 /

    90000 は Index Scan ◦ MCV によって両方の値が登録されていたため、 適切に Index Scan が選ばれた ◦ 対象行数は多いがcorrelation = 1.0(物理順とカラム値が一致)な ので、インデックススキャンが効率的 • COL_D = 'A' は Bitmap Index Scan ◦ 大まかな理由は同上と同様 ◦ correlation = 0.108(ほぼ順番バラバラ)でIndexScan非効率。 しかしCOL_D = 'A' は全体の10%程度のためBitmap Index Scan。 (Bitmap Index Scan:複数行をまとめて処理するのに効率的)
  14. 8. まとめ • 📌 ヒストグラムの役割 ◦ データの分布を記録し、クエリの実行計画を最適化する ◦ WHERE 句のフィルタリングや結合処理で、適切なスキャン方法を選択するために重要 •

    📌 ヒストグラムの種類 ◦ 等間隔:均等なビン幅(均等分布向け) ◦ 等深度:データ量を均等に分ける(偏りのあるデータ向け) ◦ ハイブリッド:等深度+MCV で最適化(製品によって仕様が異なる) • 📌 検証結果のポイント ◦ MCV に登録された値 → 適切に Seq Scan or Index Scan を選択 ◦ correlation = 1.0 に近い場合 → Index Scan が効率的 ◦ correlation = 0 に近い場合 → Seq Scan or Bitmap Index Scan が選ばれる ▪ correlation = 0 に近い場合、Seq Scan が最適になることがある! ▪ Seq Scan は、連続的なデータ読み込みによりキャッシュ効率が高く、 Index Scan のランダム I/O (O(N)) よりも速くなる場合がある! • Index Scan はインデックスを参照しつつランダムアクセスが発生 → 取得対象が多いと I/O コスト増 • Seq Scan はディスクを連続的に読み込み、 I/O が最適化される