PostgreSQL 18 中文参考文档(未翻译部分保留英文)🌐 切换到英文原版 →

14.2. 优化器使用的统计信息 #

14.2.1. 单列统计信息
14.2.2. 扩展统计信息

14.2.1. 单列统计信息 #

查询优化器需要准确预估查询在各个计算节点上产出的数据行数,以此作为代价权衡的依据。系统目录视图 pg_stats(基于底层的 pg_statistic 映射而来)存储了通过 ANALYZE 命令采集的单列物理统计信息:

  • null_frac:该字段中 NULL 空值所占的比例。

  • avg_width:该字段在磁盘存储上的平均字节物理宽度。

  • n_distinct:该字段在全表中的唯一不同取值数(若为负数,代表唯一值占总行数的比例)。

  • most_common_vals 与 most_common_freqs:高频热点值清单(MCV)及其各自对应的全局出现频次。

  • histogram_bounds:用于等频区间划分的直方图(Histogram),优化器利用直方图能够以极高精度预估范围查询(如 x > 100 AND x < 500)的选择度。

  • correlation:字段值的逻辑排序与行在物理磁盘页面上的存储顺序之间的统计相关系数。系数接近 +1 或 -1 表明物理存储与逻辑排序高度一致,走索引扫描仅需极少量顺序磁盘 I/O。

14.2.2. 扩展统计信息 #

单列统计信息默认假定不同字段之间的取值分布是完全统计独立的。然而在真实业务中,字段之间常常存在强烈的内在关联(例如“城市”字段与“省份/国家”字段之间具有完全的函数依赖)。单纯基于单列统计相乘会严重低估联合过滤的选择度,误导优化器选错计划。

通过使用 CREATE STATISTICS 命令,可以为多列组合创建扩展统计信息:

CREATE STATISTICS stts (dependencies) ON city, state FROM cities;
ANALYZE cities;

系统在底层会专门采集多列之间的函数依赖强度(Functional Dependencies)、多列唯一值统计以及多列联合高频值清单(Multivariate MCV),使优化器在面对复杂的复合条件查询时依然能够做出极其精准的行数估算。

14.2.2.1. 函数依赖统计信息 #

最基础的扩展统计信息用于追踪函数依赖(Functional Dependencies)。如果已知字段 a 的取值足以决定字段 b 的取值,则称 b 函数依赖于 a。在带有 dependencies 的统计对象中,ANALYZE 会采集列组间的关联强度系数:

CREATE STATISTICS stts (dependencies) ON city, zip FROM zipcodes;
ANALYZE zipcodes;
SELECT stxname, stxkeys, stxddependencies
  FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid)
  WHERE stxname = 'stts';

当查询同时包含这两列的过滤条件时,规划器会结合该依赖系数调整选择度,避免严重低估结果集行数。

14.2.2.1.1. 函数依赖的局限性 #

函数依赖当前仅适用于列与常量值比较的简单等值条件以及常量的 IN 子句。它不用于改善列与列比较、范围查询或 LIKE 条件的估算。此外,规划器假定所涉列的条件是兼容冗余的;若给出了不兼容条件(如城市为旧金山而邮编为洛杉矶),函数依赖统计无法推断出结果必然为零行。

14.2.2.2. 多变量非重复值计数 #

单列统计仅记录每列自身的唯一值数量。在多列聚合(如 GROUP BY a, b)场景下,单纯依靠单列数据推算联合分组数常常产生严重偏差。

通过创建带有 ndistinct 选项的统计对象:

CREATE STATISTICS stts2 (ndistinct) ON city, state, zip FROM zipcodes;
ANALYZE zipcodes;

ANALYZE 会精确测算所列字段所有组合的联合唯一值数,显著提升复杂聚合与分组查询的计划选择质量。

14.2.2.3. 多变量高频值列表 #

单列 MCV 列表无法涵盖复合谓词的真实组合频率。通过指定 mcv 选项创建统计对象:

CREATE STATISTICS stts3 (mcv) ON city, state FROM zipcodes;
ANALYZE zipcodes;

系统能够捕获跨列联合取值的实际出现频率,通过函数 pg_mcv_list_items() 可检视具体的联合高频项分布。这消除了多列过滤条件联动时的数量级预估偏差。