PostgreSQL中pg_stat_user_tables的seq_scan多大算异常?
PostgreSQL中通过pg_stat_user_tables判断缺失索引的seq_scan判定标准
问题场景
我尝试通过pg_stat_user_tables识别PostgreSQL数据库中缺少索引的表,得知seq_scan列的“较大”值是缺失索引的指标,但不清楚“较大”的判定标准:是绝对值,还是依赖表的行数?我执行了如下查询,得到的最大seq_scan为7,617,366,tup_per_scan为3,253,864。
查询语句:
SELECT relname, seq_scan, seq_tup_read / seq_scan AS tup_per_scan FROM pg_stat_user_tables WHERE seq_scan > 0;
判定标准与分析
seq_scan的“较大”不能只看绝对值,必须结合表的总行数和业务场景综合判断:- 若表本身行数很少(比如几千行以内),哪怕
seq_scan绝对值上万,全表扫描的性能开销也很低,不一定需要加索引。 - 若表行数很多,哪怕
seq_scan绝对值不算特别高,但每次扫描读取的行数(tup_per_scan)接近表总行数,说明频繁执行全表扫描,这种情况大概率缺少支撑常用查询的索引。
- 若表本身行数很少(比如几千行以内),哪怕
优化查询,加入表总行数更直观判断:
SELECT relname, seq_scan, seq_tup_read / seq_scan AS tup_per_scan, reltuples AS total_rows, ROUND((seq_tup_read / seq_scan) / reltuples::NUMERIC, 2) AS scan_ratio FROM pg_stat_user_tables JOIN pg_class ON pg_stat_user_tables.relid = pg_class.oid WHERE seq_scan > 0 ORDER BY scan_ratio DESC, seq_scan DESC;
实用判定参考:
- 当
scan_ratio(每次扫描行数/表总行数)接近1(如>0.8),且seq_scan次数较高(如上万次),说明该表被高频全表扫描,优先排查常用查询,添加合适的索引。 - 若
scan_ratio很小但seq_scan次数高,通常是小表的高频扫描,加索引收益极低,无需处理。 - 还要结合业务场景:比如报表类查询本身就是全表扫描,哪怕次数多也属于正常情况,不需要加索引。
- 当
针对你的数据:
tup_per_scan达325万,先对比对应表的总行数。如果总行数和该值接近,且seq_scan高达760多万次,说明这张表被高频全表扫描,优先优化它的查询索引。
内容的提问来源于stack exchange,提问作者ll47
相关产品推荐
相关产品推荐

