首页/数据/SQL 速查/ANALYZE 更新统计信息
性能与执行计划72 条

ANALYZE 更新统计信息

优化器依赖统计信息估算行数:数据大改动后计划变差,先 ANALYZE 再谈改写与加索引。

SQL 速查数据更新于 2026-10-13

ANALYZE 是什么

ANALYZE 收集表的统计信息——列值分布、空值比例、区分度,优化器依赖这些数据估算行数并选择访问路径。大批量导入或删除后,统计信息与现实明显脱节,计划就会变差,这时先 ANALYZE 再考虑改写 SQL 或加索引。PostgreSQL 的 ANALYZE 只读取样本、不阻塞读写,可以随时执行;autovacuum 也会按变更比例自动触发 autoanalyze,但瞬时大批量写入后建议手动补一次,别等自动任务周期。

基本信息

适用平台PostgreSQL(MySQL 的对应语句是 ANALYZE TABLE,重新统计索引基数)
语法ANALYZE [VERBOSE] 表名;不带表名则分析当前库所有表
采样精度default_statistics_target 默认 100,可按列单独提高关键列的精度
自动触发autovacuum_analyze_scale_factor 与 autovacuum_analyze_threshold
多列相关性列间强相关(城市与邮编)时用 CREATE STATISTICS 建扩展统计
查看状态pg_stat_user_tables 里的 last_analyze、last_autoanalyze、n_mod_since_analyze

典型使用场景

  • 大批量导入或删除后补齐统计信息
  • 计划突然变差、估算行数与实际差很多时先 ANALYZE 排除统计问题
  • 定期维护任务里固定执行一次,配合 VACUUM
  • 分区表逐分区分析,避免父表统计滞后
  • 关键列区分度高时提高采样精度,让估算更贴近真实分布

执行与查看

执行与查看
ANALYZE orders;                 # 收集单表统计
ANALYZE VERBOSE orders;         # 输出处理进度

-- 查看最近一次统计收集时间与未分析变更量
SELECT relname, last_analyze, last_autoanalyze,
       n_live_tup, n_mod_since_analyze
FROM pg_stat_user_tables
WHERE relname = 'orders';

-- 提高关键列采样精度后再分析,让估算更准
ALTER TABLE orders ALTER COLUMN user_id SET STATISTICS 500;
ANALYZE orders;

批量导入后的标准动作

批量导入后的标准动作
-- 导入完成后立刻补统计,避免优化器沿用旧分布
COPY orders FROM '/tmp/orders.csv' WITH (FORMAT csv, HEADER true);
ANALYZE orders;

-- 需要多列相关性时先建扩展统计
CREATE STATISTICS st_orders_city_zip (dependencies)
  ON city, zip FROM orders;
ANALYZE orders;

关键点速查

项目说明注意
执行成本只读样本,不阻塞读写可随时执行,大表采样量受参数控制
采样量default_statistics_target关键列可单独提高精度
自动触发autovacuum 的 autoanalyze按变更比例触发,瞬时大批量后可能来不及
多列相关性CREATE STATISTICS城市与邮编这类强相关列
状态查看pg_stat_user_tables关注 last_analyze 与 n_mod_since_analyze
ANALYZE 与 VACUUM 不是同一件事:前者更新统计信息让估算更准,后者回收死元组占用的空间;维护任务里两者通常都跑,但触发条件与代价不同。
导入几百万行后不执行 ANALYZE,优化器仍按旧分布选择计划,可能持续走错访问方式;建议把 ANALYZE 作为批量写入脚本的固定收尾步骤。

易错点

  • 导入大量数据后不 ANALYZE,优化器沿用旧分布,计划持续劣化
  • 完全依赖 autoanalyze 兜底,变更后不等自动周期就上线新功能
  • 把 ANALYZE 当 VACUUM 用,以为能回收死元组空间,磁盘占用没有变化
  • 对全库一次性执行 ANALYZE 而不分批,大库上耗时较长并占用大量 IO

数据来源与参考

  • PostgreSQL Documentation §13.4.3 Updating Planner Statistics
  • PostgreSQL Documentation §25.1 Routine Vacuuming
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌