前言

解释 DBeaver 的执行计划怎么看。


一、DBeaver 执行计划长什么样

在 DBeaver 中选中 SQL → 右键 → Explain Plan,会看到这样的表格:

Operation Object Rows Cost Node Type
-> Nested Loop Left Join 100 1000
  -> Index Range Scan act_ru_task 50 50
  -> Index Lookup act_ru_variable 1 5
-> Using temporary 100000 50000
  -> Table Scan (Full) act_hi_varinst 100000 30000

二、核心列的含义

1. Operation — 做了什么操作

操作名 含义 好/坏 出现场景
Table Scan (Full) 全表扫描,一行一行读 ❌ 最慢 没索引或索引没命中
Index Range Scan 走索引,只扫描一段 ✅ 快 WHERE 条件走了索引
Index Lookup 通过索引找到具体行 ✅ 最快 精准查找
Using temporary 用了临时表(内存或磁盘) ⚠️ 小心 GROUP BY、行转列
Using filesort 用文件排序 ⚠️ 小心 ORDER BY 没走索引
Nested Loop Join 嵌套循环关联 ⚠️ JOIN 两张大表时慢
Hash Join 哈希关联 大表 JOIN 时高效
Using index 只用索引,不用查表 ✅✅ 最快 覆盖索引
Using where 过滤数据 正常 WHERE 条件

2. Object — 操作的对象

就是表名或索引名,比如 act_ru_taskact_hi_varinst

3. Rows — 预估扫描行数(最关键!)

Rows 值 含义 判断
50 扫描 50 行 ✅ 很快
10000 扫描 1 万行 ⚠️ 有点慢
100000 扫描 10 万行 ❌ 慢
1000000+ 扫描百万行 ❌❌❌ 非常慢

看执行计划第一眼就看 Rows!Rows 大的地方就是慢的原因。

4. Cost — 成本估算

MySQL 内部算的一个值,数字越大越慢。一般不用太关注,看 Rows 更直观。


三、用您的项目举例

优化前的执行计划(模拟)

Operation                     | Object           | Rows   | 解读
------------------------------|------------------|--------|-----------------
Table Scan (Full)             | act_hi_varinst   | 100000 | ❌ 全表扫10万行
  Group By                    |                  | 100000 | ❌ 分组也是10万行
    Nested Loop Left Join     |                  | 100000 | 
      Table Scan (Full)       | act_ru_task      | 5000   | 
        Subquery (repeat 8x)  | same as above    | 100000 | ❌ 重复8次!

总扫描行数 ≈ 100000 × 8 = 800000

一眼看出问题:

  1. Table Scan (Full) — 全表扫描,没走索引
  2. Rows = 100000 — 扫描量大
  3. 同一个操作重复 8 次

优化后的执行计划(模拟)

Operation                     | Object           | Rows   | 解读
------------------------------|------------------|--------|-----------------
CTE user_proc_inst:           |                  |        |
  Index Range Scan            | act_ru_task      | 100    | ✅ 走索引,只查100行
    Union                     |                  | 50     |
  Index Range Scan            | act_hi_taskinst  | 50     |CTE flowable_vars:            |                  |        |
  Index Range Scan            | act_hi_varinst   | 1000   | ✅ 走索引,只查1000行
    Group By                  |                  | 1000   | 只对1000行分组

CTE approval_users:           |                  |        |
  Index Range Scan            | ACT_RU_TASK      | 100    | ✅

Main Query:                   |                  |        |
  Nested Loop Join            |                  | 100    |
    Index Range Scan          | act_ru_task      | 50     | ✅

总扫描行数 ≈ 100 + 1000 + 100 + 50 = 1250

一眼看出变好的地方:

  1. Table Scan (Full)Index Range Scan(全表扫描变索引扫描)
  2. Rows = 100000Rows = 1000(扫描量降为 1/100)

四、如何快速判断 SQL 好坏

第一眼看什么?

顺序 看什么 坏的信号 好的信号
Rows 最大的那行 几万+ 几百
type / Operation ALL(全表扫描) range, ref, const
Extra Using temporary, Using filesort Using index
有没有重复的操作 同一个表出现多次全表扫描 只有一次

一个简单的评分标准

Rows 10+  +  Full Scan    = ❌❌❌  必须优化
Rows 1+   +  Full Scan    = ❌❌    需要优化
Rows 1000+  +  Range Scan   = ⚠️      可以看看
Rows 100以下 + Index Lookup  = ✅      很好

五、实战:拿到执行计划后的排查步骤

1步:找到 Rows 最大的行
  └─ Rows = 100000 → 瓶颈在这

第2步:看这行的 Operation
  └─ Table Scan (Full) → 全表扫描,没索引
  └─ 或是重复出现多次 → 用 CTE 优化

第3步:问为什么 Rows 这么大
  └─ 没加 WHERE 条件 → 加条件
  └─ WHERE 条件没走索引 → 加索引
  └─ 就是要查这么多 → 看能不能分步查

第4步:改完再 EXPLAIN 对比
  └─ Rows 从 100000100  ✅ 优化成功
  └─ Rows 没变化 → 优化方向不对

六、DBeaver 中的快捷操作

操作 说明
选中 SQL → 右键 → Explain Plan 查看执行计划
选中 SQL → 右键 → Execute Script (Cmd+Option+X) 查看实际执行时间
选中 SQL → 右键 → Execution Plan (Cmd+Shift+E) 另一种执行计划视图

快捷键

Mac Windows 效果
Cmd + Shift + E Ctrl + Shift + E 查看执行计划
Cmd + Option + X Ctrl + Alt + X 执行脚本(看耗时)

七、一句话记忆

执行计划就是 SQL 的"体检报告",Rows 大的地方就是病灶,Full Scan 就是病名。

  • Rows 大 = 体检指标异常(❌)
  • Full Scan = 确诊了(没走索引)
  • Using temporary = 并发症(用了临时表)
  • 改完后 Rows 变小 = 指标恢复正常(✅)
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐