プランナで使用される統計情報

PostgreSQL 9.1.1文書
前のページ | 巻戻し | 第 14章性能に関するヒント | 早送り | 次のページ

# 14.2. プランナで使用される統計情報

前節で説明した通り、問い合わせプランナは、より良い問い合わせ計画を選択するために問い合わせによって取り出される行数の推定値を必要としています。 本節では、システムがこの推定に使用する統計情報について簡単に説明します。

統計情報の1つの構成要素は、各テーブルとインデックスの項目の総数と、各テーブルとインデックスが占めるディスクブロック数です。 この情報は`pg_class`の`reltuples`と`relpages`列に保持されます。 以下のような問い合わせによりこれを参照することができます。

    SELECT relname, relkind, reltuples, relpages
    FROM pg_class
    WHERE relname LIKE 'tenk1%';

           relname        | relkind | reltuples | relpages
    ----------------------+---------+-----------+----------
     tenk1                | r       |     10000 |      358
     tenk1_hundred        | i       |     10000 |       30
     tenk1_thous_tenthous | i       |     10000 |       30
     tenk1_unique1        | i       |     10000 |       30
     tenk1_unique2        | i       |     10000 |       30
    (5 rows)

ここで、`tenk1`とそのインデックスには10000行が存在し、そして、（驚くには値しませんが）インデックスはテーブルよりもかなり小さなものであることがわかります。

効率を上げるため、`reltuples`と`relpages`は処理の度には更新されず、したがって通常は多少古い値のみ所有しています。 これらは`VACUUM`、`ANALYZE`、`CREATE INDEX`などの一部のDDLコマンドによって更新されます。 スタンドアロンの`ANALYZE`、つまり`VACUUM`の一部ではないコマンドはテーブルのすべての行を読みませんので、`reltuples`の概算値を生成します。 プランナは、現在の物理的なテーブルサイズに合わせるために`pg_class`から検索した値を調整して、より高精度な近似値を持ちます。

ほとんどの問い合わせは、検証される行を制限する`WHERE`句によって、テーブル内の行の一部のみを取り出します。 したがって、プランナは`WHERE`句の選択性、つまり`WHERE`句の各条件にどれだけの行が一致するかを推定する必要があります。 この処理に使用される情報は`pg_statistic`システムカタログ内に格納されます。 `pg_statistic`内の項目は、`ANALYZE`と`VACUUM ANALYZE`コマンドによって更新され、また１から更新がかかったとしても常に概算値になります。

統計情報を手作業で確認する場合、`pg_statistic`を直接参照するのではなく、`pg_stats`ビューを参照する方が良いでしょう。 `pg_stats`はより読みやすくなるように設計されています。 さらに、`pg_stats`は誰でも読み取ることができますが、`pg_statistic`はスーパーユーザのみ読み取ることができます。 （これは、非特権ユーザが統計情報から他人のテーブルの内容に関わる事項を読み取ることを防止します。 `pg_stats`ビューは現在のユーザが読み取ることができるテーブルに関する行のみを表示するよう制限されています。） 例えば、以下を行うことができます。

    SELECT attname, inherited, n_distinct,
           array_to_string(most_common_vals, E'\n') as most_common_vals
    FROM pg_stats
    WHERE tablename = 'road';

     attname | inherited | n_distinct |          most_common_vals
    ---------+-----------+------------+------------------------------------
     name    | f         |  -0.363388 | I- 580                        Ramp+
             |           |            | I- 880                        Ramp+
             |           |            | Sp Railroad                       +
             |           |            | I- 580                            +
             |           |            | I- 680                        Ramp
     name    | t         |  -0.284859 | I- 880                        Ramp+
             |           |            | I- 580                        Ramp+
             |           |            | I- 680                        Ramp+
             |           |            | I- 580                            +
             |           |            | State Hwy 13                  Ramp
    (2 rows)

同じ列に対して2行が表示されていることに注意してください。 1つは`road`テーブルが始まる継承階層(`inherited`=`t`)全体に相当し、もう1つは`road`テーブル自身(`inherited`=`f`)のみを含むものです。

`ANALYZE`により`pg_statistic`に格納される情報量、具体的には、それぞれの列に対する`most_common_vals`内と`histogram_bounds`配列のエントリの最大数は、`ALTER TABLE SET STATISTICS`コマンドによって列ごとに、default_statistics_target設定パラメータを設定することによってグローバルに設定することができます。 現在のデフォルトの上限は100エントリです。 この上限を上げることで、特に、少し変わったデータ分布を持つ列でより正確なプランナの推定が行われますが、`pg_statistic`により多くの容量が必要になり、多少推定計算にかかる時間が多くなります。 反対に上限を下げることは、単純なデータ分布の列に対して順当です。

プランナによる統計情報の使用に関する詳細については第57章を参照してください。

前のページ | ホーム | 次のページ
`EXPLAIN`の利用 | 上に戻る | 明示的な`JOIN`句でプランナを制御する