Oracle 执行计划怎么看?EXPLAIN PLAN 和 DBMS_XPLAN 怎么用?
简化版
Oracle 执行计划用于查看 SQL 的访问路径、连接方式、行数估算和成本。常用方式是 EXPLAIN PLAN 生成预计计划,再用 DBMS_XPLAN.DISPLAY 查看;也可以用 DBMS_XPLAN.DISPLAY_CURSOR 查看实际执行过的游标计划。看计划时重点关注表访问方式、索引使用、JOIN 方法、估算行数是否偏差、排序聚合和谓词信息。
详细版
常见执行计划节点包括:
TABLE ACCESS FULL:全表扫描;TABLE ACCESS BY INDEX ROWID:通过索引定位后回表;INDEX RANGE SCAN:索引范围扫描;INDEX UNIQUE SCAN:唯一索引扫描;NESTED LOOPS:嵌套循环连接;HASH JOIN:哈希连接;MERGE JOIN:排序合并连接;SORT ORDER BY:排序;FILTER:过滤条件。
优化时不要只看“有没有走索引”,还要看数据量、选择性、统计信息、JOIN 顺序、估算行数和实际行数的差距。
完整版教学
一、执行计划解决什么问题
SQL 写出来只是描述“要什么数据”,数据库还要决定“怎么拿数据”。执行计划就是 Oracle 优化器给出的执行路径。
例如同样是查订单:
SELECT * FROM orders WHERE user_id = :userId;
Oracle 可能选择全表扫描,也可能选择索引扫描。选择哪个,取决于统计信息、数据量、条件选择性、索引结构和成本估算。
二、EXPLAIN PLAN 查看预计计划
常见写法:
EXPLAIN PLAN FOR
SELECT * FROM orders WHERE user_id = 100;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
它展示的是优化器预计会怎么执行。注意预计计划不一定等于真实运行时计划,因为真实执行可能受绑定变量、统计信息、游标共享、自适应优化等影响。
三、DISPLAY_CURSOR 查看实际游标计划
如果 SQL 已经执行过,可以使用 DBMS_XPLAN.DISPLAY_CURSOR 查看游标中的计划,通常更接近真实情况。
面试时可以这样表达:EXPLAIN PLAN 适合预估和学习,线上诊断更希望看实际执行过的 SQL 计划、执行统计和谓词信息。
如果能看到 actual rows、buffer gets 等信息,就更容易判断瓶颈。
四、先看访问路径
常见访问路径:
- 全表扫描:扫描整张表或大量数据块;
- 索引唯一扫描:通过唯一索引精确定位;
- 索引范围扫描:按索引范围取多行;
- 回表:索引找到 ROWID 后再访问表数据块。
全表扫描不一定错,小表或命中大量数据时全表扫描可能更合适。真正的问题是访问路径是否符合数据规模和业务预期。
五、再看 JOIN 方式
Oracle 常见 JOIN 方法:
- Nested Loops:外表结果少、内表有索引时适合;
- Hash Join:大数据量等值连接常见;
- Sort Merge Join:两边排序后合并,适合特定范围和排序场景。
如果外层返回大量行,内层又反复回表,Nested Loops 可能很慢。如果两个大表等值连接,Hash Join 可能更合适。
六、统计信息会影响计划质量
优化器依赖统计信息估算行数和成本。如果统计信息过旧,或者数据分布严重倾斜,执行计划就可能选错。
常见问题:
- 估算行数和实际行数差很多;
- 索引明明存在却不用;
- JOIN 顺序不合理;
- 绑定变量导致不同值共用不合适计划;
- 分区统计信息不完整。
SQL 优化时,加索引只是手段之一,更新统计信息、改写 SQL、调整数据模型也很重要。
七、常见误区与追问
| 关注点 | 看什么 | 常见判断 |
|---|---|---|
| 访问路径 | FULL、INDEX、ROWID | 是否符合返回数据量 |
| JOIN 方法 | Nested Loops、Hash、Merge | 是否匹配两侧数据规模 |
| 估算质量 | E-Rows 与 A-Rows | 偏差大常提示统计问题 |
易错点:
EXPLAIN PLAN是预计计划,不一定等于真实运行计划。线上诊断更希望看实际游标计划、谓词信息、行数和 buffer gets。
例如优化器估算某条件只返回 100 行,实际返回 100000 行,可能选择 Nested Loops 反复回表;如果内表每次回表 3 个数据块,就可能产生 30 万级随机块访问。此时问题不一定是“没建索引”,也可能是统计信息过旧、绑定变量值倾斜、直方图缺失或 SQL 谓词写法让选择性估错。
- 误区:Oracle 执行计划里走索引就一定快。 回表很多、随机 I/O 大、选择性差时,索引扫描可能比全表扫描更慢。
- 误区:全表扫描一定是坏计划。 小表、命中大比例数据、并行扫描或数据仓库场景下,全表扫描可能合理。
- 误区:EXPLAIN PLAN 就代表线上真实执行。 真实游标计划可能受绑定变量、统计信息、自适应优化和执行环境影响。
- 追问:DBMS_XPLAN.DISPLAY_CURSOR 有什么价值? 它能看已执行 SQL 的游标计划,配合执行统计更接近真实问题。
- 追问:谓词信息为什么重要? 它能区分访问谓词和过滤谓词,判断条件是在索引阶段生效,还是取数后再过滤。
- 追问:统计信息如何影响计划? 优化器依赖统计估算行数和成本,过旧或缺少直方图会导致 JOIN 顺序、访问路径选择错误。
八、加强记忆
看 Oracle 执行计划按顺序来:访问路径、JOIN 方法、行数估算、谓词信息、排序聚合、统计信息。不要只盯着“有没有走索引”,优化器真正比较的是成本;索引扫描、回表和大量随机 I/O 有时也会比全表扫描更慢。