文章目录
- 1 概述
- 1.1 思维导图
- 1.2 概念
- 2 执行计划
- 2.1 预估的
- 2.2 真实的
- 3 示例
- 4 备选命令
1 概述
什么是 Oracle 的执行计划?
执行计划是一条查询语句在 Oracle 中的执行过程或访问路径的描述
简单一点说,就是: Oracle 是如何执行 sql 语句的。
- 比如说,就像咱去一个地方,事先会计划好怎么坐车一样。先坐公交车到哪儿再坐地铁,oracle 的执行计划也是如此,就是一步一步地执行 sql。
- oracle 的执行计划是很复杂的,一般我们看到的执行计划都是 oracle 通过内部算法计算以后选择的一个消耗比较少的执行路径,就像我们去哪里也要选择一条捷径一样的道理。
1.1 思维导图
1.2 概念
- 表访问方式 - (全表扫描、通过 rowid 扫描、通过索引扫描)
- 表连接方式详解 - (nested loops、hash join、sort merge join)
2 执行计划
2.1 预估的
最简单的方式:通过 pl/sql developer 的 F5 进行查看:
2.2 真实的
前提说明:
(1) 该用户(如:scott)要有访问动态视图的权限(最常用的用户:system)
grant select any dictionary to scott;
(2) sql 已执行完成
具体步骤:
1. 获取执行计划的统计信息(两种方式) '下列两条命令必须在同一个窗口执行哦'
alter session set statistics_level = all; -- 推荐
select * from dual;
-- 设置前,可以用下列两种方式查询当前的 参数信息
-- select * from v$parameter t where t.name = 'statistics_level';
-- show parameter statistics_level
或(每次查询时,每个 sql 语句都加上下列 hint):
select /*+ gather_plan_statistics */ * from dual;
2. 找出执行语句的 'sql_id'
select t.*
from v$sql t
where t.sql_text like '%select * from%'
order by t.last_active_time desc;
3. 根据 'sql_id' 查出 '真实执行计划(最近一条)'
select * from table(dbms_xplan.display_cursor('cyfzxc61h3g3r',null,'allstats last'));
3 示例
获取 真实的执行计划
1. 执行的 sql 语句:
select /*+ gather_plan_statistics*/
t.*
from scott.emp t
where t.empno >= 7782;
2. 找出执行语句的 ‘sql_id’:
select t.*
from v$sql t
where t.sql_text like '%where t.empno >= 7782%'
order by t.last_active_time desc;
3. 根据 ‘sql_id’ 查出 ‘真实执行计划(最近一条)’:
select * from table(dbms_xplan.display_cursor('92dkjj0sw6wjr',null,'allstats last'));
最终结果:
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0
Connected as system@orcl
SQL> select * from table(dbms_xplan.display_cursor('92dkjj0sw6wjr',null,'allstats last'));
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
SQL_ID 92dkjj0sw6wjr, child number 0
-------------------------------------
select /*+ gather_plan_statistics*/ t.* from scott.emp t where
t.empno >= 7782
Plan hash value: 169057108
------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 8 |00:00:00.01 | 2 |
| 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 5 | 8 |00:00:00.01 | 2 |
|* 2 | INDEX RANGE SCAN | PK_EMP | 1 | 5 | 8 |00:00:00.01 | 1 |
------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("T"."EMPNO">=7782)
20 rows selected
SQL>
参数说明:
Starts 该 sql 执行的次数
E-Rows 预计返回的行数
A-Rows 实际返回的行数。可以和 E-Rows 比对,确定哪一步出现了问题
A-Time 每一步实际执行的时间
Buffers 每一步实际执行的逻辑读或一致性读
Reads 每一步实际执行的物理读
Writes 每一步实际执行的物理写
OMem 最优执行模式所需的内存评估值
1Mem one-pass模式所需的内存评估值
Used_Mem 则为当前操作实际执行时消耗的内存
括号里面为(发生磁盘交换的次数,1次即为One-Pass,大于1次则为Multi_Pass,如果没有使用磁盘,则显示0)
4 备选命令
SQL> set col 100 -- 设置显示 100 列(若命令窗口显示不全时使用)
SQL>
SQL> clear -- 清屏