SQL Academy · 课时

识别并修复慢查询

使用 pg_stat_statements、log_min_duration_statement 和 EXPLAIN 找出慢查询,并采取针对性的修复措施

第 4 / 4 课14 个步骤

识别并修复慢查询 是 CoddyKit 上的免费 SQL Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 SQL Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 SQL Academy 课程共包含 4 节课。

第 1 步:找出运行缓慢的查询

不要盲目优化。可以使用:

  • pg_stat_statements — 按总耗时列出最耗时的查询
  • log_min_duration_statement — 记录超过阈值的查询
  • pgBadger — 根据日志生成易读的报告

pg_stat_statements 设置

启用扩展并配置共享预加载库:

-- postgresql.conf
shared_preload_libraries = 'pg_stat_statements'

-- After restart:
CREATE EXTENSION pg_stat_statements;

最耗时的前 10 个查询

对于任何 DBA 来说,最有用的单条查询是:

SELECT query,
       calls,
       total_exec_time,
       mean_exec_time,
       rows
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

记录慢查询

设置阈值并查看日志:

-- postgresql.conf
log_min_duration_statement = '500ms'
-- All queries running > 500ms are logged.

第 2 步:使用 EXPLAIN ANALYZE 重现

对于每个运行缓慢的查询,请在具有代表性的环境中(使用类似生产环境的数据)运行 EXPLAIN ANALYZE。请查看:

  • 按实际耗时计算最大的节点
  • 估算行数与实际行数之间最大的差距
  • 是否使用了正确的索引

常见修复方法

  • WHERE / JOIN 列缺少索引
  • 无法使用索引的谓词(列上使用了函数)— 添加表达式索引或重写查询
  • 统计信息已过期 — 运行 ANALYZE
  • 数据类型错误(导致隐式转换)— 修正列类型
  • OR 条件 — 重写为多个单条件查询的 UNION
  • SELECT * 获取了过多数据 — 缩小投影范围

过期的统计信息

如果估算行数与实际行数相差很大,请先运行 ANALYZE:

ANALYZE orders;
-- Or rely on autovacuum to do it periodically.

索引检查

列出表上的索引及其大小:

SELECT indexrelname, pg_size_pretty(pg_relation_size(indexrelid))
FROM pg_stat_user_indexes
WHERE relname = 'orders'
ORDER BY pg_relation_size(indexrelid) DESC;

未使用的索引

找出从未使用过的索引:

SELECT schemaname, relname, indexrelname, idx_scan
FROM pg_stat_user_indexes
WHERE idx_scan = 0
ORDER BY pg_relation_size(indexrelid) DESC;
-- Consider dropping them — they slow writes for no read benefit.

锁竞争

有时查询之所以“缓慢”,是因为正在等待锁。请检查 pg_stat_activity 中的 wait_event:

SELECT pid, state, wait_event_type, wait_event, query
FROM pg_stat_activity
WHERE state <> 'idle';

查询重写模式

  • 将过滤条件移到 WHERE 中
  • 使用 JOIN + GROUP BY 替换 SELECT 中的相关子查询
  • 使用带索引查询的 UNION ALL 替换 OR
  • 使用窗口函数替代自连接
  • 在规划器判断困难时,使用公用表表达式物化重复的子查询

反复调整

性能调优是一个循环:测量 → 提出假设 → 修改 → 测量。不要凭猜测行事。

回顾

使用 pg_stat_statements 找出慢查询,使用 EXPLAIN ANALYZE 进行诊断,使用索引 / ANALYZE / 重写进行修复,然后反复调整。

快速检查

哪个 PostgreSQL 扩展可以按总运行时间列出最耗时的查询?

免费开始

用 AI 导师学习 SQL — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
46
课程
183

常见问题解答

「识别并修复慢查询」课时是免费的吗?

是的 — 「识别并修复慢查询」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 SQL Academy 课程的其余内容,请升级到 CoddyKit PRO。 SQL Academy 课程共包含 4 节课。

「识别并修复慢查询」这节课中我会学到什么?

使用 pg_stat_statements、log_min_duration_statement 和 EXPLAIN 找出慢查询,并采取针对性的修复措施 你通过在浏览器中直接运行的动手代码来练习 SQL Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 SQL Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 SQL Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「识别并修复慢查询」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 SQL Academy 课中编写并运行代码吗?

能。每节 SQL Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 阅读 EXPLAIN 与 EXPLAIN ANALYZE
  2. 顺序扫描与索引扫描
  3. 哈希连接、合并连接与嵌套循环
  4. 识别并修复慢查询
← 返回 SQL Academy