# 创建统计

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

# 描述

创建统计将创建一个新的扩展统计对象跟踪有关指定表、外部表或物化视图的数据。统计对象将在当前数据库中创建,并由发出命令的用户拥有。

创建统计命令有两种基本形式。第一种形式允许收集单个表达式的单变量统计信息,提供类似于表达式索引的好处,而无需索引维护的开销。这种形式不允许指定统计类型,因为各种统计类型仅指多变量统计。该命令的第二种形式允许收集关于多个列和/或表达式的多元统计信息,可选择指定要包括的统计信息类型。此表单还将自动收集列表中包含的任何表达式的单变量统计信息。

如果给出了模式名称(例如,创建统计信息 myschema.mystat ...) 然后在指定的模式中创建统计对象。否则,它会在当前模式中创建。统计对象的名称必须与同一模式中的任何其他统计对象的名称不同。

# 参数

如果不存在

如果同名的统计对象已经存在,不要抛出错误。在这种情况下发出通知。请注意,这里只考虑统计对象的名称,而不考虑其定义的详细信息。

统计名称

要创建的统计对象的名称(可选的模式限定)。

统计种类

要在此统计对象中计算的多元统计类型。目前支持的种类是不明显,它启用了 n 个不同的统计量,依赖关系,它启用函数依赖统计,以及mcv这启用了最常见的值列表。如果省略此子句,则所有支持的统计类型都包含在统计对象中。如果统计定义包括任何复杂的表达式,而不仅仅是简单的列引用,则会自动构建单变量表达式统计。有关详细信息,请参阅第 14.2.2 节第 72.2 节.

列名

要被计算的统计信息覆盖的表列的名称。仅在构建多元统计数据时才允许这样做。必须至少指定两个列名或表达式,并且它们的顺序不重要。

表达

计算统计信息涵盖的表达式。这可用于在单个表达式上构建单变量统计信息,或作为多列名称和/或表达式列表的一部分来构建多变量统计信息。在后一种情况下,将为列表中的每个表达式自动构建单独的单变量统计信息。

表名

包含计算统计信息的列的表的名称(可选模式限定)。

# 笔记

您必须是表的所有者才能创建读取它的统计信息对象。但是,一旦创建,统计对象的所有权就独立于基础表。

表达式统计信息是针对每个表达式的,类似于在表达式上创建索引,但它们避免了索引维护的开销。为统计对象定义中的每个表达式自动构建表达式统计。

# 例子

创建表t1具有两个功能相关的列,即第一列中的值的知识足以确定另一列中的值。然后在这些列上构建功能依赖统计信息:

CREATE TABLE t1 (
    a   int,
    b   int
);

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

ANALYZE t1;

-- the number of matching rows will be drastically underestimated:
EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0);

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

ANALYZE t1;

-- now the row count estimate is more accurate:
EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0);

如果没有功能依赖统计,规划者会假设这两个在哪里条件是独立的,并且会将它们的选择性相乘以得出一个非常小的行数估计值。有了这样的统计数据,规划者认识到在哪里条件是冗余的,不会低估行数。

创建表格t2有两个完全相关的列(包含相同的数据),这些列上有一个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;

-- valid combination (found in MCV)
EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 1);

-- invalid combination (not found in MCV)
EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 2);

MCV列表为规划师提供了有关表中通常出现的特定值的更详细信息,以及表中未出现的值组合的可选性上限,使其能够在这两种情况下生成更好的估计值。

创建表格t3并使用该列上的表达式运行查询。如果没有扩展的统计信息,规划器就没有关于表达式的数据分布的信息,而是使用默认估计值。规划者也没有意识到,截短到月份的日期的值完全由截短到当天的日期的值决定。然后,表达式和NDistint统计信息建立在这两个表达式的基础上:

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;

-- the number of matching rows will be drastically underestimated:
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;

-- build ndistinct statistics on the pair of expressions (per-expression
-- statistics are built automatically)
CREATE STATISTICS s3 (ndistinct) ON date_trunc('month', a), date_trunc('day', a) FROM t3;

ANALYZE t3;

-- now the row count estimates are more accurate:
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;

如果没有表达式和ndistinct统计信息,规划者就没有关于表达式的不同值数量的信息,并且必须依赖默认估计。假设等式和范围条件具有0.5%的选择性,并且表达式中的不同值的数量与列中的相同(即唯一)。这导致在前两个查询中严重低估了行数。此外,规划者没有关于表达式之间关系的信息,因此它假定这两个表达式哪里分组条件是独立的,并将它们的选择性相乘,从而得出聚合查询中严重高估的组数。由于表达式缺乏准确的统计信息,这进一步加剧了这种情况,迫使计划者对从列的ndistinct派生的表达式使用默认的ndistinct估计值。有了这些统计数据,规划者认识到这些条件是相互关联的,并得出更准确的估计。

# 兼容性

没有创建统计数据SQL标准中的命令。

# 另见

改变统计数据,丢弃统计数据