| name | pg-top-sql-analyze |
| description | 基于 pg_stat_statements 对 PostgreSQL 实例做两阶段快照采集与差值分析,找出总耗时、单次最慢、高频调用、IO消耗、WAL生成量、返回行数异常等多维度 TOP SQL,并给出索引/改写/批量化等具体优化建议与健康评分。触发场景包括:'帮我分析一下这个库的慢SQL'、'找TOP SQL'、'pg_stat_statements 分析'、'数据库性能诊断'、'哪些SQL最耗资源'、'帮我看看这个实例的负载画像'、'SQL优化建议'、'缓存命中率低怎么排查'、用户给出 PostgreSQL 连接信息(host/port/user/password/dbname)并希望做性能巡检或SQL调优时。即使用户只说'帮我看看这个库最近跑得怎么样'或'这些SQL要怎么优化'并提供了连接信息,也应使用本技能。 |
| tags | ["PostgreSQL","TOP SQL","瓶颈分析"] |
| platform | ["claude-code","cursor"] |
| author | digoal |
| version | 1.0.0 |
| license | GNU General Public License v2.0 |
| homepage | https://github.com/digoal/skills |
PostgreSQL TOP SQL 性能分析师
基于 pg_stat_statements 扩展,对指定 PostgreSQL 实例做两次快照采集、计算增量差值,输出多维度 TOP SQL 排行榜与逐条优化建议,最终给出全局健康评分与负载画像。适用于生产巡检、上线前后对比、慢查询专项治理。
前置要求
- 一个可用的 psql 客户端(或等效的 SQL 执行通道)以及目标实例的连接信息:host、port、user、password、dbname。
- 目标实例已安装并启用
pg_stat_statements 扩展。
- 连接账号至少具备读取
pg_stat_statements 视图和执行 pg_stat_statements_reset()(若使用重置模式)的权限。
- 不缓存、不外传密码等连接凭据;凭据仅用于当次连接,不写入日志或输出报告。
工作流程
Step 0:连接与前置条件检查
- 使用给定连接信息连接目标库,执行
scripts/00_precheck.sql 完成以下检查:
pg_stat_statements 扩展是否已安装(查询 pg_extension)。
pg_stat_statements.track 是否为 all(查询 pg_settings);若为 top 或 none,非 SELECT 语句可能采集不到。
- PostgreSQL 主版本号(决定是否有
total_plan_time 字段,13 以下版本跳过计划时间分析)。
- 若扩展未安装或未启用,立即终止,向用户输出:
检测到 pg_stat_statements 未启用。请在目标库执行:
1. postgresql.conf 中添加:shared_preload_libraries = 'pg_stat_statements'
2. 重启实例后执行:CREATE EXTENSION pg_stat_statements;
3. 建议同时设置:pg_stat_statements.track = 'all'
完成后重新运行本次分析。
- 若
track 不是 all,给出警告但可继续(非 SELECT 语句统计可能不完整),并在最终报告中注明此局限。
Step 1:选择采集模式
主动询问用户使用哪种模式(默认推荐"差值模式",因为不影响全局统计数据):
| 模式 | 做法 | 适用场景 | 风险 |
|---|
| 重置模式(默认不用) | 采集 → pg_stat_statements_reset() → 等待 → 再采集 | 需要精确的"纯增量"数据,且能接受清空历史统计 | 会清空全局统计计数器,影响其他正在依赖这些统计的监控/分析,仅在非生产核心时段或用户明确授权后执行 |
| 差值模式(推荐默认) | 采集快照1(不 reset)→ 等待 → 采集快照2 → 对 calls/total_exec_time/rows 等累计字段做差值 | 生产环境常规巡检,不希望影响其他监控 | 若采集间隔内发生了 reset 或语句因 pg_stat_statements.max 被淘汰,某些 queryid 的差值可能为负或缺失,需要识别并在报告中注明 |
- 使用重置模式前,必须输出醒目警告:「⚠️ 即将执行 pg_stat_statements_reset(),将清空该实例全局 SQL 统计历史,请确认已获得授权」,并等待用户确认后才可执行。
- 差值模式下,若发现快照2中某 queryid 的 calls/total_exec_time 小于快照1(说明期间发生过重置或该记录被淘汰后新生成),将该记录标记为「数据不连续,本次已剔除」,不纳入排行榜。
Step 2:两阶段数据采集
- 记录
snapshot1_time,执行 采集全量 数据(含 references/collected_fields.md 中列出的全部字段)保存到上下文/临时表。