PostgreSQL执行计划的使用与查看

PostgreSQL执行计划

pg的执行计划和MySQL的执行计划的显示有一点不一样,我得补习一下。

1. 基本命令:EXPLAIN

EXPLAIN 命令会显示 PostgreSQL 规划器为给定的 SQL 语句生成的执行计划。它不会实际执行该语句,只是预测其执行路径和成本。

语法:

sql 复制代码
EXPLAIN your_sql_statement;

示例:

sql 复制代码
EXPLAIN SELECT * FROM users WHERE email = 'test@example.com';

输出内容解读:

输出是一个树形结构,一般是从下向上看执行步骤,只需要关注下面几点:

  • 操作类型 (Node Type) :表示执行的操作,如 Seq Scan(顺序扫描)、Index Scan(索引扫描)、Hash Join(哈希连接)、Sort(排序)等。

  • 关联关系 (Relationship) :显示表之间的关联方式,如 INNERLEFT

  • 成本 (Cost) :包含两个数字,例如 (cost=0.00..15.03 rows=1 width=44)

    • 0.00:启动成本,即获取第一行数据的预估成本。
    • 15.03:总成本,即获取所有行数据的预估成本。
    • rows=1:预估返回的行数。
    • width=44:预估每行数据的平均宽度(字节)。
  • 实际数据 (Actual) :如果你使用 EXPLAIN ANALYZE,这里会显示实际执行的数据。


2. 关键命令:EXPLAIN ANALYZE

这是最常用且最强大的组合。EXPLAIN ANALYZE 会实际执行 SQL 语句,并返回真实的执行计划和实际的执行统计信息(如时间、返回行数)。

语法:

sql 复制代码
EXPLAIN ANALYZE your_sql_statement;

示例:

sql 复制代码
EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 123 AND status = 'shipped';

输出内容解读:

除了 EXPLAIN 的信息外,还会增加:

  • 实际时间 (Actual Time) :例如 (actual time=0.018..0.019 rows=1 loops=1)

    • 0.018:获取第一行实际花费的时间(毫秒)。
    • 0.019:获取所有行实际花费的时间(毫秒)。
    • rows=1:实际返回的行数。
    • loops=1:该节点执行的次数。
  • 执行时间 :计划末尾的 Execution Time 显示了整个查询的实际总耗时。

⚠️ 重要警告

对于 INSERT, UPDATE, DELETE, CREATE TABLE AS 等会修改数据的语句,EXPLAIN ANALYZE 会真的执行这些操作!在生产环境中使用前,请务必在测试环境确认,或者将其包裹在一个事务中并回滚:

sql 复制代码
BEGIN;
EXPLAIN ANALYZE UPDATE table_name SET column = value WHERE condition;
ROLLBACK; -- 分析完成后回滚,不会真正修改数据

3. 如何解读和分析执行计划

查看执行计划的目的是找到性能瓶颈。以下是一些常见的需要关注的性能红灯

  1. 全表扫描 (Seq Scan)

    • 对大数据表进行全表扫描通常性能很差。检查是否可以为 WHERE 子句中的条件字段创建索引。
  2. 昂贵的操作

    • Sort: 昂贵的排序操作,尤其是在处理大量数据时。考虑是否可以通过索引来避免排序。
    • Hash Join / Hash Aggregate: 这些操作需要在内存中构建哈希表,如果数据量大,可能会占用大量内存甚至使用磁盘临时文件,导致变慢。
    • Nested Loop: 如果内循环的数据集很大,性能会非常差。

总结步骤

  1. 找到慢查询:通过日志查询。

  2. 使用 EXPLAIN ANALYZE:在测试环境中运行它来获取真实的执行计划。

  3. 寻找瓶颈:从上到下阅读执行计划,寻找全表扫描、不准确的预估、昂贵的排序或哈希操作。

  4. 提出优化方案

    • 增加索引 (最常用):为 WHERE, JOIN, ORDER BY, GROUP BY 子句中的字段添加索引。
    • 优化查询 :重写查询,避免不必要的操作(如 SELECT *,复杂的子查询)。
相关推荐
雪隐14 小时前
个人电脑玩AI-09让5060 Ti给你打工——让 AI 读懂你的资料
人工智能·后端
小满zs15 小时前
Go语言第一章(入门)
后端·go
用户67570498850215 小时前
Kafka 太重?试试 NSQ:一个优雅到极致的消息队列
后端·go
铁皮饭盒15 小时前
S3已成为文件存储标准,阿里/腾讯/华为云都支持,Bun率先原生支持
前端·javascript·后端
洛卡卡了15 小时前
Claude Code Hook,当 CLAUDE.md 规则不生效时,我们还需要强制拦截机制
后端·agent·claude
用户67570498850215 小时前
RabbitMQ 太重,Kafka 太复杂?Go 开发者:Asynq分布式任务队列就刚刚好
后端·go
AlbertLuo16 小时前
CodeMirror使用: 编写一个在线编辑HTML、JS、CSS文件,网页的模板页面-初实现
后端
SamDeepThinking16 小时前
裁掉那个差程序员后,给你看团队里高手的代码:这个习惯,希望你有
java·后端·程序员
Oneslide17 小时前
windows 11远程桌面连Ubuntu GNOME 远程登录频繁断开
后端
咕白m62517 小时前
用 Python 实现一键批量查找与替换 Excel 数据
后端·python