前言

EXPLAIN 不是“语法糖”,而是唯一能让你提前看到 SQL 执行路径的官方工具。
把路径看懂,才知道慢在哪、该动索引还是动数据。

下面给出可落地的读法:先 MySQL,再 Hive,各自只有三个核心指标,记住就能用。


一、MySQL:看“查数据”的三板斧

1. 准备实验表

CREATE TABLE orders(
    order_id BIGINT PRIMARY KEY,
    user_id  BIGINT,
    amount   DECIMAL(10,2),
    KEY idx_uid (user_id)
)ENGINE=InnoDB;

2. 两条 SQL 对比

-- SQL-1 主键查
SELECT * FROM orders WHERE order_id = 12345;

-- SQL-2 普通列查
SELECT * FROM orders WHERE user_id = 12345;

3. 分别跑 EXPLAIN

EXPLAIN SELECT * FROM orders WHERE order_id = 12345\G
EXPLAIN SELECT * FROM orders WHERE user_id  = 12345\G

4. 输出截断(只留关键列)

SQL-1

type: const
key: PRIMARY
rows: 1
Extra: NULL

SQL-2

type: ref
key: idx_uid
rows: 104
Extra: Using where

5. 怎么读这三列

列名含义安全阈值超标怎么办
type访问类型至少达到 range 以上出现 ALL 就全表扫描,必须加索引或改写
key实际索引必须不是 NULLNULL = 没索引可用,考虑新建或更换索引
rows预估行数尽量 < 原表 5%过大说明索引区分度差,考虑联合索引或覆盖索引

6. 进阶:Extra 出现这 4 个词要警惕

  • Using filesort —— 内存/磁盘排序,ORDER BY 没走索引

  • Using temporary —— 建了临时表,GROUP/DISTINCT 没走索引

  • Range checked for each record —— 索引选择代价高,可能抖动

  • Using where; Using index —— 完美,覆盖索引不回表

7. 小结(背下来)

type ≠ ALL → key ≠ NULL → rows 足够小
满足这三条,MySQL 层面基本没大坑;任何一条破功,就加索引或改 SQL。


二、Hive:看“跑任务”的三板斧

1. 准备实验表

CREATE TABLE orders(
    order_id BIGINT,
    user_id  BIGINT,
    amount   DECIMAL(10,2)
)
STORED AS ORC;

2. 一条聚合 SQL

SELECT user_id, COUNT(*) cnt
FROM   orders
GROUP  BY user_id;

3. 跑 EXPLAIN

EXPLAIN
SELECT user_id, COUNT(*) cnt
FROM   orders
GROUP  BY user_id;

4. 核心输出(Stage 依赖 + Stage plan)

STAGE DEPENDENCIES:
  Stage-1  root
  Stage-0  depends on Stage-1

STAGE PLANS:
  Stage-1: Map
     TableScan  -->  Reduce Output (hash distribute by user_id)
  Stage-0: Reduce
     Group By   -->  Final File Output

5. 怎么读这三点

检查点含义危险信号调优动作
Stage 数量越多越慢>3 就要看合并子查询、减少嵌套
Map/Reduce 之间有没有 Sort + Shuffle数据倾斜时 Reduce 极慢加盐重写、开启 skew join
TableScan 行数原始数据量远大于分区过滤后行数加分区、加 ORC bloom filter

6. 两条实战命令辅助

-- 看真实输入行数
EXPLAIN DEPENDENCY ...;

-- 看运行时算子
EXPLAIN EXTENDED ...;

TableScan 后面的 rawDataSizenumRows 对比,就能知道分区下推有没有生效。

7. 小结(背下来)

Stage 少 → Shuffle 小 → TableScan 行数=分区过滤后行数
满足这三条,Hive 作业基本健康;否则就改分区、加盐或调并行度。


三、一张图总结(保存即可)

维度MySQL EXPLAINHive EXPLAIN
核心目标避免全表扫描避免多余 Stage/Shuffle
关键指标type, key, rowsStage 数、Shuffle 关键字、TableScan 行数
优化手段加索引、覆盖索引、改写 SQL加分区、加盐、合并子查询、调并行度
典型危险type=ALLReduce 卡住、数据倾斜

四、给你一套“出问题时”的固定步骤

MySQL 慢

  1. EXPLAIN 看 type/key/rows

  2. type=ALL → 新建索引

  3. key=NULL → 检查列类型/字符集是否一致

  4. rows 过大 → 建联合索引或限制返回列(覆盖索引)

Hive 慢

  1. EXPLAIN 看 Stage 数

  2. Stage>3 → 合并子查询、先 WITH tmp AS 物化

  3. 看有没有 distribute by + sort by → 倾斜时改加盐

  4. TableScan 行数远大于分区行数 → 加分区或 ANALYZE TABLE 更新元数据


五、结语

记住两句话,现场就不会慌:

  • MySQL 看“查”——别让 type 变成 ALL

  • Hive 看“跑”——别让 Stage 无限增加

把 EXPLAIN 当成体检报告,而不是参考书。报告只看关键指标,超标就动刀,别的花哨字段先忽略,优化自然有章法。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐