

如图,刚做过数据迁移将postgresql14中的数据及表迁移到了kingbase数据库中,但发现查询数据在一定范围内内匹配到索引,超过之后就是全表扫描
解决方法:VACUUM ANALYZE sc_surface_water_hour
在 PostgreSQL 中,
VACUUM ANALYZE sc_surface_water_hour; 是一个组合命令,主要作用和对索引选择的影响如下:一、命令的核心作用
该命令由
VACUUM 和 ANALYZE 两个操作组成,同时完成数据清理和统计信息更新:-
VACUUM 的作用当表中的数据被删除(
DELETE)或更新(UPDATE)时,PostgreSQL 不会立即物理删除旧数据,而是将其标记为 “死元组”(dead tuples)。这些死元组会占用磁盘空间,且在扫描表时会被无意义地读取,降低查询效率。VACUUM的作用是:- 回收死元组占用的磁盘空间,使其可被新数据复用;
- 更新表的可见性映射(visibility map),帮助查询跳过无需扫描的 “全死” 数据块,提升扫描效率。
-
ANALYZE 的作用PostgreSQL 的查询规划器(Query Planner)在生成执行计划时,需要依赖表的统计信息来判断最优路径(例如 “用索引扫描还是全表扫描”)。
ANALYZE的作用是:- 收集表的关键统计数据,包括:表的总行数、各字段的非空值数量、唯一值分布、数据块数量、字段值的频率分布等;
- 将这些统计信息存储在系统表(如
pg_statistic)中,供查询规划器使用。
二、为什么会影响索引的选择?
查询规划器选择是否使用索引,核心依据是
ANALYZE 收集的统计信息。具体来说:-
统计信息决定 “成本评估”规划器会基于统计信息计算不同执行路径的 “成本”(如 I/O 成本、CPU 成本)。例如:
- 如果统计信息显示某字段的查询条件(如
WHERE status = 'error')只能过滤出极少数行(比如 1%),规划器会认为 “索引扫描” 更高效(先查索引定位行,再回表取数据); - 如果统计信息显示过滤后的数据量很大(比如 30% 以上),规划器可能认为 “全表扫描” 更高效(避免索引扫描的回表开销)。
- 如果统计信息显示某字段的查询条件(如
-
过时统计信息会导致错误选择当表经过大量插入、更新、删除后,旧的统计信息会与实际数据分布脱节。例如:
- 实际表中已新增 100 万行,但统计信息仍记录为 10 万行,规划器可能误判 “索引扫描成本更低”,但实际执行时因数据量过大导致效率下降;
- 某字段原本重复值很少(适合索引),但经过大量更新后重复值占比极高(不适合索引),但统计信息未更新,规划器仍会错误选择索引。
-
VACUUM 间接辅助统计准确性
VACUUM清理死元组后,表的实际数据量(活元组数量)会更准确,ANALYZE基于清理后的数据收集统计信息,能进一步提升规划器对 “数据规模” 的判断准确性,间接影响索引选择。
总结
VACUUM ANALYZE 本质是通过清理无效数据和更新统计信息,让查询规划器能基于表的真实状态评估执行成本,从而更合理地选择是否使用索引(或选择哪个索引),最终优化查询性能。