SQL执行计划
sql
EXPLAIN FORMAT=JSON SELECT ...; -- 机器可读的 JSON 格式
sql 显示预估的执行计划。
EXPLAIN SELECT * FROM user WHERE age > 18;
实际执行并返回每个节点的真实行数、时间、缓冲区命中情况。
sql
EXPLAIN (ANALYZE, BUFFERS, TIMING) SELECT ...;
二、分析执行计划的关键点
1. 访问类型(type)—— MySQL 重点关注
- system / const:理想情况,最多匹配一行,如按主键查询。
- eq_ref:使用唯一索引进行关联。
- ref:使用非唯一索引查找。
- range:使用索引进行范围扫描(>、<、BETWEEN、IN 等)。
- index:全索引扫描,比全表好,但仍需遍历所有索引项。
- ALL:全表扫描,通常是大问题,说明缺少有效索引。
2. 实际执行 vs 预估行数(rows / actual rows)
- rows(MySQL)或 预估行数(PG):优化器估算需要扫描的行数。
- 如果 实际行数远大于预估行数,说明统计信息过时,需执行 ANALYZE TABLE(MySQL)或 ANALYZE(PG)。
3. 额外信息(Extra)—— MySQL 常见警告
- Using filesort:需要额外的排序操作,通常需要为 ORDER BY 建索引。
- Using temporary:使用临时表,常见于 GROUP BY 或 DISTINCT 无索引的情况,应优化。
- Using index:覆盖索引,不需要回表,性能好。
- Using where:在存储引擎层过滤后再由 MySQL 服务层过滤,通常可接受,但如果伴随 ALL 则需改进。
- Using index condition:索引下推(ICP),优化了部分条件在索引层过滤,有利。
4. 连接类型(JOIN)
- Nested Loop:适用于小表驱动大表,内表最好有索引。
- Hash Join(PG / MySQL 8.0+):适合两表数据量较大且无索引的等值连接,内存占用高。
- Merge Join:排序后归并,较少出现。
5. 操作节点(PostgreSQL 特有)
- Seq Scan:顺序扫描,数据量大时需优化。
- Index Scan:索引扫描。
- Bitmap Index Scan:先通过索引位图定位,再回表读取,适合多条件组合。
- Sort / Group / Aggregate:排序和聚合操作,若消耗过高可考虑索引排序或改写 SQL。
查看11道真题和解析
