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 | 非常高 | 极端情况(很少需要) |
总结要点
-
保持默认 :
default_statistics_target = 100在现代 PostgreSQL 中仍是标准默认值,对大多数场景足够 -
按需调整 : 应先通过
ALTER TABLE ... SET STATISTICS按列调优,而非直接修改全局默认值 -
权衡成本: 提高统计目标会增加 ANALYZE 时间和系统表空间占用
-
验证效果: 调整后检查查询计划的估算准确性是否改善