用 EXPLAIN 分析 MySQL 和 PostgreSQL 查询计划
用 EXPLAIN 和 EXPLAIN ANALYZE 观察数据库如何执行查询,是学习索引和优化的第一步。
#type / howto
#status / growing
#tech / dev / backend
#resource / mysql
#resource / postgresql
[!info] related notes
- 前置笔记: 数据库索引, SQL 查询执行流程
- 相关 MOC: 数据库 MOC
- 相关资源: MySQL, PostgreSQL
用 EXPLAIN 分析 MySQL 和 PostgreSQL 查询计划
目标
通过最小例子看懂数据库到底是全表扫描、索引扫描,还是做了代价更高的连接和排序。
前置条件
- 有一张可查询的测试表
- 知道某个字段上是否建了索引
步骤
- 先准备一个带索引的查询条件
CREATE INDEX idx_users_email ON users(email);
- 在 MySQL 中执行
EXPLAIN
SELECT id, name
FROM users
WHERE email = 'alice@example.com';
- 在 PostgreSQL 中执行
EXPLAIN ANALYZE
SELECT id, name
FROM users
WHERE email = 'alice@example.com';
- 重点看三个问题:
- 是全表扫描还是索引扫描
- 预计扫描多少行
- 真实扫描代价和估计是否接近
验证
- 去掉索引后再跑一遍,观察计划变化
- 改成一个命中很多行的条件,再观察优化器是否仍然选择索引
常见问题
- MySQL 常用
EXPLAIN;PostgreSQL 更常把EXPLAIN ANALYZE当成学习入口 - 不要只看“有没有用索引”,还要看扫描行数、回表成本和排序代价
ANALYZE会真的执行查询,在线上环境要谨慎对待重查询