PostgreSQL从入门到进阶
🏠 首页
  • 开始学习

    • PostgreSQL介绍
    • 安装配置
  • 基础教程

    • 数据库与表
    • 数据类型
    • CRUD操作
    • WHERE条件
  • 进阶查询

    • 联表查询
    • 聚合函数
    • 子查询
    • 视图
  • 性能优化

    • 索引优化
    • 查询优化
    • EXPLAIN分析
  • 事务处理
  • 触发器
  • 存储过程
  • JSON数据
  • 博客系统
  • 用户管理系统
  • 最佳实践
🔗 编程指南
🏠 首页
  • 开始学习

    • PostgreSQL介绍
    • 安装配置
  • 基础教程

    • 数据库与表
    • 数据类型
    • CRUD操作
    • WHERE条件
  • 进阶查询

    • 联表查询
    • 聚合函数
    • 子查询
    • 视图
  • 性能优化

    • 索引优化
    • 查询优化
    • EXPLAIN分析
  • 事务处理
  • 触发器
  • 存储过程
  • JSON数据
  • 博客系统
  • 用户管理系统
  • 最佳实践
🔗 编程指南
  • 开始之前

    • 教程介绍
    • 什么是PostgreSQL?
    • 安装PostgreSQL
  • 基础入门

    • 数据库和表的概念
    • 数据类型详解
    • 增删改查操作(CRUD)
    • 查询条件WHERE
  • 进阶查询

    • 多表联查JOIN
    • 聚合函数
    • 子查询
    • 视图VIEW
  • 性能优化

    • 索引详解
    • 查询优化
    • 执行计划分析
  • 高级特性

    • 事务处理
    • 触发器
    • 存储过程
    • JSON数据
  • 实战项目

    • 实战项目:博客系统
    • 实战项目:用户管理系统
    • 最佳实践

执行计划分析

嗨!我是长安。今天教你看懂PostgreSQL的"心思"!

🎯 什么是执行计划?

执行计划是PostgreSQL告诉你:我是怎么执行这条SQL的。

-- 查看执行计划
EXPLAIN SELECT * FROM users WHERE email = 'test@email.com';

-- 查看实际执行情况
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@email.com';

📊 读懂EXPLAIN

EXPLAIN SELECT * FROM posts WHERE user_id = 1;

-- 输出:
-- Seq Scan on posts  (cost=0.00..35.50 rows=10 width=100)
--   Filter: (user_id = 1)

关键信息:

  • Seq Scan:顺序扫描(全表扫描)
  • cost=0.00..35.50:成本估算(启动成本..总成本)
  • rows=10:预计返回10行
  • width=100:每行平均100字节

🎯 常见的扫描方式

Seq Scan(顺序扫描)

全表扫描,慢:

EXPLAIN SELECT * FROM posts;
-- Seq Scan on posts

解决方法:添加WHERE条件,创建索引

Index Scan(索引扫描)

使用索引,快:

CREATE INDEX idx_posts_user_id ON posts(user_id);
EXPLAIN SELECT * FROM posts WHERE user_id = 1;
-- Index Scan using idx_posts_user_id on posts

Index Only Scan(索引覆盖扫描)

只读索引不回表,最快:

CREATE INDEX idx_posts_user_title ON posts(user_id, title);
EXPLAIN SELECT title FROM posts WHERE user_id = 1;
-- Index Only Scan using idx_posts_user_title on posts

Bitmap Scan(位图扫描)

多个索引组合:

EXPLAIN SELECT * FROM posts 
WHERE user_id = 1 AND status = 'published';
-- Bitmap Heap Scan on posts
--   Recheck Cond: ...
--   -> BitmapAnd
--       -> Bitmap Index Scan on idx_user_id
--       -> Bitmap Index Scan on idx_status

💡 使用EXPLAIN ANALYZE

-- 实际执行并统计
EXPLAIN ANALYZE 
SELECT * FROM posts WHERE user_id = 1;

-- 输出:
-- Index Scan ... (cost=0.29..8.31 rows=1 width=100)
--                (actual time=0.025..0.026 rows=1 loops=1)
-- Planning Time: 0.123 ms
-- Execution Time: 0.045 ms

关键指标:

  • actual time:实际执行时间
  • rows:实际返回行数
  • Planning Time:计划时间
  • Execution Time:执行时间

🎮 实战案例

-- 慢查询
EXPLAIN ANALYZE
SELECT * FROM posts p
JOIN users u ON p.user_id = u.id
WHERE p.created_at > '2023-01-01'
ORDER BY p.created_at DESC
LIMIT 10;

-- 看执行计划,发现问题:
-- 1. Seq Scan on posts(需要索引)
-- 2. Hash Join(可能需要调整)
-- 3. Sort(可以用索引避免排序)

-- 优化:创建索引
CREATE INDEX idx_posts_created ON posts(created_at DESC);
CREATE INDEX idx_posts_user_id ON posts(user_id);

-- 再次分析
EXPLAIN ANALYZE
SELECT * FROM posts p
JOIN users u ON p.user_id = u.id
WHERE p.created_at > '2023-01-01'
ORDER BY p.created_at DESC
LIMIT 10;

-- 现在使用Index Scan,速度快多了!

📚 下一步

掌握了执行计划分析,你就能精准优化SQL了!

接下来学习事务处理!


长安的技巧:

  • EXPLAIN看计划
  • EXPLAIN ANALYZE看实际执行
  • 关注Seq Scan,考虑加索引
  • 关注actual time,看实际性能

多用EXPLAIN,SQL优化事半功倍!🚀

最近更新: 2025/12/1 18:21
Prev
查询优化