oracle执行计划
Oracle 执行计划(Execution Plan)是优化器(Optimizer)生成的用于执行 SQL 语句的详细步骤描述。通过分析执行计划,可以理解 SQL 语句如何访问数据、使用索引、执行连接操作等,从而优化查询性能。
一、获取执行计划
1. 使用 EXPLAIN PLAN
命令
EXPLAIN PLAN FOR
SELECT * FROM employees WHERE department_id = 10;-- 查看生成的执行计划
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
2. 使用 AUTOTRACE
SET AUTOTRACE TRACEONLY EXPLAIN;
SELECT * FROM employees WHERE department_id = 10;
3. 从动态性能视图中获取实际执行计划
-- 查找 SQL 的 SQL_ID
SELECT sql_id, sql_text FROM v$sql WHERE sql_text LIKE '%SELECT * FROM employees%';-- 使用 DBMS_XPLAN 显示实际执行计划
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('sql_id', null, 'ALLSTATS LAST'));
4. 使用 SQL Developer 或 Toad 等工具
二、执行计划核心要素
1. 访问路径(Access Path)
-
全表扫描(TABLE ACCESS FULL):逐行扫描整张表,适用于小表或缺乏有效索引。
-
索引扫描(INDEX SCAN):
-
INDEX UNIQUE SCAN:唯一索引精确查找。
-
INDEX RANGE SCAN:索引范围扫描。
-
INDEX FULL SCAN:按索引顺序扫描全部条目。
-
INDEX FAST FULL SCAN:多块读取索引(类似全表扫描)。
-
2. 连接方式(Join Method)
-
嵌套循环连接(NESTED LOOPS):适合小数据集驱动大表,通过索引快速定位。
-
哈希连接(HASH JOIN):适合大数据集等值连接,需内存构建哈希表。
-
排序合并连接(MERGE JOIN):需预先对两个数据集排序。
3. 执行顺序
-
执行计划按 树形结构 展示,从叶子节点(数据源)向根节点(最终结果)执行。
-
缩进越深 的步骤越先执行。
4. 关键指标
-
Cost:优化器估算的相对资源消耗(CPU、I/O),值越小越好。
-
Rows:优化器预估返回的行数(与实际差异可能导致性能问题)。
-
Time:预估执行时间(Oracle 12c+ 支持)。
三、示例执行计划解读
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10 | 690 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 10 | 690 | 3 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | DEPT_IDX | 10 | | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
-
步骤解读:
-
Id=2:使用索引
DEPT_IDX
进行范围扫描(INDEX RANGE SCAN
),预估返回 10 行。 -
Id=1:通过
ROWID
回表获取完整数据行(TABLE ACCESS BY INDEX ROWID
)。 -
Id=0:返回最终结果。
-
四、常见优化场景
1. 全表扫描效率低
-
优化方法:创建合适索引,确保统计信息准确。
2. 索引未被使用
-
可能原因:隐式类型转换、函数导致索引失效,如
WHERE UPPER(name) = 'JOHN'
。
3. 连接方式不合理
-
强制连接方式:使用提示(Hints),如
/*+ USE_HASH(employees departments) */
。
4. 统计信息过时
更新统计信息:
EXEC DBMS_STATS.GATHER_TABLE_STATS('HR', 'EMPLOYEES');
五、高级工具
SQL Monitor(Oracle 11g+):实时监控长时间运行的 SQL。
SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR(sql_id => 'abc123') FROM dual;
-
AWR/ASH 报告:分析历史 SQL 性能。