You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL:pg_stat_user_tables中seq_scan计数及查询定位问题

问题解答

1. Bitmap Heap Scan 会不会被统计为 pg_stat_user_tables 中的 seq_scan?

明确说:不会。

pg_stat_user_tables里的seq_scan字段统计的是针对该表的**纯顺序扫描(Sequential Scan)**次数——也就是数据库直接从头到尾扫描整个表数据块的操作。而Bitmap Heap Scan是索引扫描流程的一部分:通常先通过Bitmap Index Scan生成符合条件的行的位图,再根据位图去堆表中抓取对应的行,这个过程属于索引驱动的扫描,不会被计入seq_scan。

你看到seq_scan非零,说明确实有查询在执行全表顺序扫描,不是Bitmap Heap Scan导致的。

2. 如何定位执行顺序扫描的查询?

这里给你几个实用的方法,按推荐程度排序:

方法一:用 pg_stat_statements 追踪历史查询(最推荐)

pg_stat_statements是PostgreSQL的核心扩展,能记录所有执行过的查询的详细统计信息,包括每个查询触发的顺序扫描次数。

首先确保扩展已启用(如果没开,需要先在postgresql.conf里设置shared_preload_libraries = 'pg_stat_statements',然后重启数据库,再执行CREATE EXTENSION pg_stat_statements;)。

然后执行以下查询来找出触发顺序扫描的语句:

SELECT
  queryid,
  query,
  calls,
  seq_scan,
  total_time,
  rows
FROM pg_stat_statements
WHERE seq_scan > 0
ORDER BY seq_scan DESC;

这个结果会按顺序扫描次数从多到少排序,你可以直接看到哪些查询在频繁触发全表扫。

方法二:用 pg_stat_activity 实时捕获当前运行的顺序扫描

如果想抓正在执行的全表扫,可以查询pg_stat_activity,过滤出当前活跃且正在做Seq Scan的进程:

SELECT
  pid,
  datname,
  usename,
  query,
  state
FROM pg_stat_activity
WHERE state = 'active'
  AND query LIKE '%Seq Scan on%';

注意这个只能抓到当前正在运行的查询,适合临时排查突发的seq_scan。

方法三:通过数据库日志定位

可以开启PostgreSQL的日志功能来记录相关查询:

  • 在postgresql.conf中设置log_statement = 'all'(会记录所有查询,适合临时排查,不要长期开,避免日志过大),或者log_min_duration_statement = 100(记录执行时间超过100ms的查询,更高效)。
  • 然后查看数据库日志文件,搜索关键词Seq Scan on,就能找到对应的查询语句和执行时间。

方法四:针对可疑表用 EXPLAIN ANALYZE 验证

如果怀疑某个表的seq_scan是特定查询导致的,可以对该查询执行EXPLAIN ANALYZE,看实际执行计划里是否有Seq Scan节点。有时候预估的EXPLAIN计划和实际执行计划不一致(比如表的统计信息过时),这时候EXPLAIN ANALYZE会展示真实的执行路径。

另外,如果你发现预估计划和实际执行计划不符,建议对目标表执行ANALYZE your_table;更新统计信息,让优化器生成更准确的计划。


内容的提问来源于stack exchange,提问作者Xephonia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:54:07