PostgreSQL default_statistics_target参数详解

default_statistics_target 是 PostgreSQL 的配置参数,用于控制执行 ANALYZE(或通过自动清理进行的自动分析)时收集表列统计信息的详细程度

  • 默认值 : 100

  • 数据类型: integer

  • 允许范围: 1 -- 10000

  • 生效级别: 用户级别(无需重启即可更改,影响后续的 ANALYZE 操作)

参数实际控制的内容

该参数不直接表示"采样 100 行",而是:

  • PostgreSQL 会从表中采样大约 300 × default_statistics_target 行数据

    (300 倍乘数源于构建良好直方图的统计采样历史建议)

  • 默认值 100 → 约采样 30,000 行

  • 基于这些样本,PostgreSQL 构建(最多):

    • default_statistics_target最常见值(MCV)列表条目

    • default_statistics_target 个直方图边界

    • 加上其他标量统计信息(空值比例、不同值估算等)

值越高 → 统计信息越详细 → 通常行数估算更准确 → 查询计划更好

(代价是 ANALYZE / 自动清理运行时间更长 + pg_statistic 占用更多空间)

何时需要调整?

通常不需要全局提高该值。默认值 100 对大多数工作负载已经足够。

常见的调高场景:

  • 数据分布极度偏斜/不规则(例如某个值出现在 40% 的行中,同时存在许多罕见值)

  • EXPLAIN 显示基数/行数估算严重错误(相差几个数量级)

  • 某些过滤条件查询计划不佳,即使最近执行过 ANALYZE

更好的实践(几乎所有情况下)

复制代码
-- 不要直接提高全局默认值,而是针对特定列调整
ALTER TABLE orders ALTER COLUMN customer_id    SET STATISTICS 300;
ALTER TABLE events  ALTER COLUMN event_type    SET STATISTICS 500;
ALTER TABLE logs    ALTER COLUMN user_agent    SET STATISTICS 1000;

-- 然后执行
ANALYZE orders;
-- 或等待autovacuum

这种方式只针对有问题的列,避免对每张表都减慢 ANALYZE 速度。

常用检查/修改命令

复制代码
-- 查看当前设置
SHOW default_statistics_target;

-- 全局设置(影响新列和没有显式目标的列)
SET default_statistics_target = 300;           -- 仅当前会话
ALTER SYSTEM SET default_statistics_target = 300;  -- 永久生效(需要重载配置)

-- 查看当前各列的统计目标
sql 复制代码
SELECT 
    n.nspname AS schema_name,
    c.relname AS table_name,
    a.attname AS column_name,
    a.attstattarget AS statistics_target
FROM pg_attribute a
JOIN pg_class     c ON c.oid = a.attrelid
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE a.attnum > 0                -- exclude system columns (like tableoid, ctid)
  AND NOT a.attisdropped          -- exclude dropped columns
  AND c.relkind IN ('r', 'p')     -- ordinary tables + partitioned tables
  AND n.nspname NOT IN ('pg_catalog', 'information_schema')
ORDER BY 1, 2, 3;

参数值对比表

采样行数(约) MCV / 直方图槽位 ANALYZE 成本 典型使用场景
100 ~30,000 100 默认 大多数表(良好的平衡)
300--500 ~9万--15万 300--500 中等 偏斜列,常见调优
1000 ~300,000 1000 较高 非常偏斜的数据,罕见值
10000 ~300万 10000 非常高 极端情况(很少需要)

总结要点

  1. 保持默认 : default_statistics_target = 100 在现代 PostgreSQL 中仍是标准默认值,对大多数场景足够

  2. 按需调整 : 应先通过 ALTER TABLE ... SET STATISTICS 按列调优,而非直接修改全局默认值

  3. 权衡成本: 提高统计目标会增加 ANALYZE 时间和系统表空间占用

  4. 验证效果: 调整后检查查询计划的估算准确性是否改善

相关推荐
先吃饱再说17 小时前
存储的进化:从 MySQL 到浏览器缓存,数据到底住在哪?
数据库
Nturmoils17 小时前
字段太多看不全,ksql 的展开模式和输出控制怎么用
数据库·后端
Databend19 小时前
Agent 轨迹分析与归因的数据工程实践
大数据·数据库·agent
这个DBA有点耶20 小时前
SQL改写进阶:标量子查询的“隐形代价”与消除实战
数据库·mysql·架构
smallyoung21 小时前
数据库乐观锁深度解析:MySQL、PostgreSQL 实战 + Spring Boot 集成指南
数据库·mysql·postgresql
parade岁月21 小时前
MySQL JOIN解析:朴实无华但食之有味
数据库·后端
用户31693538118321 小时前
MySQL服务无法启动问题解决全记录
数据库
vivo互联网技术1 天前
从 10 分钟到 1 秒:ES 深度分页任意跳页的三轮优化实战
服务器·数据库·redis·elasticsearch·深度分页
倔强的石头_2 天前
《Kingbase护城河》——猎捕慢查询:执行计划的微观解析与索引调优实战
数据库
SelectDB2 天前
Apache Doris Python UDF:让 SQL 直接调用 Python 生态,支撑 Agent 时代复杂业务逻辑
大数据·数据库·python