他のバージョンの文書 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

CREATE STATISTICS

CREATE STATISTICS — 拡張統計情報を定義する

概要

CREATE STATISTICS [ IF NOT EXISTS ] statistics_name
    ON ( expression )
    FROM table_name

CREATE STATISTICS [ IF NOT EXISTS ] statistics_name
    [ ( statistics_kind [, ... ] ) ]
    ON { column_name | ( expression ) }, { column_name | ( expression ) } [, ...]
    FROM table_name

説明

CREATE STATISTICSは指定したテーブル、外部テーブル、マテリアライズドビューのデータを追跡する新しい拡張統計オブジェクトを作成します。 統計オブジェクトは現在のデータベースに作成され、コマンドを実行したユーザに所有されます。

CREATE STATISTICSコマンドには2つの基本的な形式があります。 1つ目の形式では、1つの式に対して単変量統計を集めることができ、式インデックスと同様の利点をインデックスの保守のオーバーヘッドを伴わずに提供します。 様々な統計の種別は多変量統計だけに関連しますので、この形式では統計の種別を指定できません。 コマンドの2つ目の形式では、複数の列や式の多変量統計を集めることができ、含まれる統計の種別もオプションで指定できます。 この形式では、自動的にリストに含まれる式の単変量統計も集められます。

スキーマ名が指定された場合(例:CREATE STATISTICS myschema.mystat ...)、統計オブジェクトは指定したスキーマ内に作成されます。 スキーマ名を指定しなければ、現在のスキーマ内に作成されます。 統計オブジェクトの名前は、同じスキーマ内のどの統計オブジェクトとも異なるものでなければなりません。

パラメータ

IF NOT EXISTS

同じ名前の統計オブジェクトが既に存在していてもエラーを発生させません。 この場合、注意メッセージが発行されます。 この場合、統計オブジェクトの名前だけが問題にされ、その定義の詳細は考慮されないことに注意してください。

statistics_name

作成する統計オブジェクトの名前です(スキーマ修飾も可)。

statistics_kind

この統計オブジェクト内で計算する多変量統計の種別です。 現在サポートされる種別は、N個別値統計を有効にするndistinct、関数的依存統計を有効にするdependencies、最頻値の一覧を有効にするmcvです。 この句を省略すると、統計オブジェクトのすべてのサポート対象の統計種別が含まれます。 単変量式統計は、統計の定義に単なる列の参照ではなく複雑な式が含まれていれば、自動的に構築されます。 より詳細な情報は14.2.2および75.2を参照してください。

column_name

統計計算の対象となるテーブル列の名前です。 これは多変量統計を構築するときにのみ可能です。 少なくとも2つの列名または式を指定しなければなりません。順序は重要ではありません。

expression

統計計算の対象となる式です。 これは1つの式に対して単変量統計を構築する場合や、多変量統計を構築する複数の列名や式のリストの一部として使われます。 後者の場合、リスト内の各式に対して自動的にそれぞれの単変量統計が構築されます。

table_name

統計情報が計算される列があるテーブルの名前(オプションでスキーマ修飾可)です。継承とパーティションの取り扱いについてはANALYZEを参照してください。

注釈

テーブルを読み取る統計オブジェクトを作るには、そのテーブルの所有者でなければなりません。 しかし、統計オブジェクトが作成された後は、その所有者と対象となるテーブルは無関係になります。

式統計は式ごとのものであり、インデックスの保守のオーバーヘッドを避けられるということ以外は式にインデックスを作るのと似ています。 式統計は、統計オブジェクト定義内の各式に対して自動的に構築されます。

拡張統計処理は現在、プランナによってテーブル結合に対して行なわれる選択性の見積もりには使用されていません。 この制限は、PostgreSQLの将来のバージョンで削除される可能性があります。

関数従属性のある2つの列を含むテーブルt1を作成します。 つまり、第1の列の値を知っていれば、それだけでもう一方の列の値がわかる、というものです。 その次に、これらの列の間に関数的依存統計を構築します。

CREATE TABLE t1 (
    a   int,
    b   int
);

INSERT INTO t1 SELECT i/100, i/500
                 FROM generate_series(1,1000000) s(i);

ANALYZE t1;


-- マッチする行の数は非常に低く見積もられる
EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0);

CREATE STATISTICS s1 (dependencies) ON a, b FROM t1;

ANALYZE t1;


-- 行数の見積もりがより正確になる
EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0);

関数的依存統計がなければ、プランナは2つのWHERE条件を独立なものとみなすため、それらの選択性を掛け算して、非常に小さな行数見積もりを導きます。 このような統計があれば、プランナはWHERE条件が冗長であることを認識し、行数を低く見積もりません。

(同一のデータの入った)完全に相関のある2つの列を持つテーブルt2を作成し、2つの列の最頻値(MCV)の一覧を作成します。

CREATE TABLE t2 (
    a   int,
    b   int
);

INSERT INTO t2 SELECT mod(i,100), mod(i,100)
                 FROM generate_series(1,1000000) s(i);

CREATE STATISTICS s2 (mcv) ON a, b FROM t2;

ANALYZE t2;


-- 有効な組み合わせ(MCV内で見つかる)
EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 1);


-- 無効な組み合わせ(MCV内で見つからない)
EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 2);

最頻値の一覧は、テーブルによく現れる特定の値に関するものだけでなく、テーブルに現れない値の組み合わせの選択の上限に関するより詳細な情報もプランナに与えますので、両方の場合に対してより良く見積もりができるようになります。

タイムスタンプの列1つのテーブルt3を作成し、その列の式を使う問い合わせを実行します。 拡張統計なしでは、プランナはその式に対するデータ分布についての情報がなく、デフォルトの評価を使います。 プランナは、月で切り捨てられた日付の値は日にちで切り捨てられた日付の値により完全に決められることにも気付きません。 それから、この2つの式に対して、式統計とN個別値統計を構築します。

CREATE TABLE t3 (
    a   timestamp
);

INSERT INTO t3 SELECT i FROM generate_series('2020-01-01'::timestamp,
                                             '2020-12-31'::timestamp,
                                             '1 minute'::interval) s(i);

ANALYZE t3;


-- マッチする行数は大幅に過小評価されます。
EXPLAIN ANALYZE SELECT * FROM t3
  WHERE date_trunc('month', a) = '2020-01-01'::timestamp;

EXPLAIN ANALYZE SELECT * FROM t3
  WHERE date_trunc('day', a) BETWEEN '2020-01-01'::timestamp
                                 AND '2020-06-30'::timestamp;

EXPLAIN ANALYZE SELECT date_trunc('month', a), date_trunc('day', a)
   FROM t3 GROUP BY 1, 2;


-- 式の組み合わせに対してN個別値統計を構築します
-- (式ごとの統計は自動的に構築されます)
CREATE STATISTICS s3 (ndistinct) ON date_trunc('month', a), date_trunc('day', a) FROM t3;

ANALYZE t3;


-- 行数の評価はより正確になります。
EXPLAIN ANALYZE SELECT * FROM t3
  WHERE date_trunc('month', a) = '2020-01-01'::timestamp;

EXPLAIN ANALYZE SELECT * FROM t3
  WHERE date_trunc('day', a) BETWEEN '2020-01-01'::timestamp
                                 AND '2020-06-30'::timestamp;

EXPLAIN ANALYZE SELECT date_trunc('month', a), date_trunc('day', a)
   FROM t3 GROUP BY 1, 2;

式統計とN個別値統計がなければ、プランナは式の異なる値の数についての情報がなく、デフォルトの評価に頼らなければなりません。 等価と範囲の条件は0.5%の選択性を持つと仮定され、式内の異なる値の数はその列の数と同じ(すなわち一意)と仮定されます。 これは、最初の2つの問い合わせでの行数の著しい過小評価という結果を招きます。 さらに、プランナは式の間の関係について情報がないので、2つのWHEREGROUP BY条件が独立であると仮定し、その選択性を掛け合わせるので、集約問い合わせでグループの数のひどい過大評価をしてしまいます。 これは、式に対する正確な統計がないことによりさらに悪化し、その列のN個別値から導かれる式に対するデフォルトのN個別値評価を使うことをプランナに強制します。 そのような統計があれば、プランナは条件が相互に関係していることを認識し、ずっとより正確な評価をします。

互換性

標準SQLにCREATE STATISTICSコマンドはありません。

関連項目

ALTER STATISTICS, DROP STATISTICS