発展関連トピック
統計情報とオプティマイザ
定義
統計情報とは、テーブルやカラムの行数・値の分布・NULL率などをオプティマイザが参照する要約データであり、これが古いと実行計画が最適でなくなる。
インデックスを使うかどうかは統計情報が決める
DBの中では「クエリオプティマイザ」がSQLを見て、複数の実行計画候補の中からコスト最小のものを選びます。 このコスト見積りは統計情報(各カラムの値の分布、行数、NULL率など)に基づきます。
検索する status:
オプティマイザが持っている分布
= 古い分布。実際とはずれている
pending33% · 330K 行
shipped33% · 330K 行
cancelled34% · 340K 行
なぜ古くなる?
大量INSERT/DELETE 直後や、データ分布が変化した直後は、DBが把握している分布と実際がずれる。 統計情報を更新するコマンドで最新化する必要がある。
オプティマイザの見積り
WHERE status = 'shipped'
推定該当行数
330,000/ 1,000,000
閾値 20% (=200,000行) との比較で選択
選ばれたアクセス方法
Seq Scan
「対象が多い」と見積もったので全表を順に読む方が速いと判断。
オプティマイザは「対象行の割合が閾値(ここでは
20%)以下ならインデックス、それより多ければフルスキャン」と判断する。 統計情報が古いと 誤った 割合で判断し、最適でないプランを選ぶ。インデックスを使わない判断もある
テーブルの多くの行が該当するクエリでは、インデックス経由でランダムアクセスを繰り返すよりもフルスキャンの方が速い。 オプティマイザはこれを見積りコストで判断します。「インデックスを貼ったのに使われない」の原因のほとんどは、この見積りで「使わない方が速い」と判断されているか、統計情報が古くて誤った判断が下されているかのどちらかです。
統計情報が古いとどうなるか
- 大量INSERT直後: 実際にはインデックスが効かない量なのにインデックスを選んでしまう
- 大量DELETE直後: インデックスが有効なのに、統計上「多くの行が該当する」と誤認して使わない
- データ分布の変化: 元は偏っていたstatusが均等になったのに古い分布で判断してしまう
こうした場合は、統計情報を更新するコマンドを実行して最新の分布に合わせます(コマンド名はRDBMSごとに異なる)。
よくある疑問
Q.統計情報はいつ更新される?
A.多くのRDBMSは自動更新の仕組みを持っていますが、大量のバルクロードやデータ分布が急変した直後は手動で統計情報の更新コマンドを実行した方が安全です。
Q.カーディナリティとは?
A.そのカラムに含まれる異なる値の数のこと。カーディナリティが高いほどインデックスが効きやすく、低い(例: is_deleted のような真偽値)と部分インデックスの方が有効なことが多い。
Q.ヒストグラムは何のため?
A.値の分布を段階的に表現したもの。データが偏っている場合(例: 特定のstatusに9割集中)、単純な平均だけでは判断できないため、ヒストグラムを見て「どの値なら少ないか」を推定します。
関連トピック
もっと学びたい方へ(おすすめ書籍)
本セクションはAmazonアソシエイトのリンクを含みます。購入いただくと運営者に紹介料が入る場合があります。
オンライン個別指導
もっと深くDBを学びたい方へ。
たいてっくが、SQL・データベース設計・パフォーマンスチューニング・ IPAデータベーススペシャリスト対策まで、1対1で学習をサポートします。まずは無料相談から。