SQL语句从应用服务器发生到数据库服务器要经历过编译后才可以执行,这个执行计划就是编译后的可执行代码。执行计划就是比较抽象而易懂的概要设计流程图啦!
获取执行计划有几种方法?
1 工具级别
比如说使用PL/SQL Developer; TOAD SQLPLUS 。这些工具需要在当前用户下创建个表,叫做PLAN_TABLE。我们先来看PL/SQL这个工具来说说看,其他TOAD基本差不多。
新建个查询窗口,输入SELECT * FROM DBA_OBJECTS;按下F5

我们看到这个是默认设置的执行计划,这个就是我们访问数据库所有对象的。
第一个字段是说明,也就是操作方法;
第二个字段 显示是对象拥有者;
第三个字段 是具体对象名称,USERS 表 I_USER#索引之类的。
第四个字段 是成本,是访问该对象 通过公式计算出来的付出代价。
第五个字段 Cardinality 是返回行数.
第六个字段 Bytes 很明显返回是大小。
图中间部分 Optimizer goal是优化算法 目前是返回所有行。
在中间那个像是播放按钮的是 第一个字段操作方法前后顺序。
最后一个扳手图标 是可以自定义显示栏的。我们先自定义一下

我们调选了一些

再看比较多信息的执行计划:

看不清楚的话,就双击么么哒!
这里增加几个ID 就不解释了,就是方便看执行计划具体操作的上下级关系。
另外细化了成本,添加了IO成本,CPU成本。
增加 Access predicates,Filter predicates 这两个栏位是说你的WHERE条件,哪个属于定存谓词,哪个属于过滤谓词。
Partition Start, Partition Stop 如果涉及到分区表就看具体是哪个分区ID了。
Temp space是消耗 临时空间数量。
Qblock Name:表示查询子块;
后面两个 Projection,Search column 不了解。
1.2 SQLPLUS
先创建自定义的表:
create table shark_objects as select * from dba_objects'

主要是设置 SET AUTOTRACE ON 就可以了
如果没有可以如下赋下权限
(2)作为SYSTEM 登录SQL*Plus;
(3)运行@utlxplan;
(4)运行CREATE PUBLIC SYNONYM PLAN_TABLE FOR PLAN_TABLE;
(5)运行GRANT ALL ON PLAN_TABLE TO PUBLIC。
通过设置AUTOTRACE 系统变量可以控制这个报告:
SET AUTOTRACE OFF:不生成AUTOTRACE 报告,这是默认设置。
SET AUTOTRACE ON EXPLAIN:AUTOTRACE 报告只显示优化器执行路径。
SET AUTOTRACE ON STATISTICS:AUTOTRACE 报告只显示SQL 语句的执行统计信息。
SET AUTOTRACE ON:AUTOTRACE 报告既包括优化器执行路径,又包括SQL 语句的执行统计信息。
SET AUTOTRACE TRACEONLY:这与SET AUTOTRACE ON 类似,但是不显示用户的查询输出(如果有的话)。
我们选择 SET AUTOTRACE TRACEONLY;

这个执行计划返回信息比较一般般,Operation 就是操作方法,Name就是操作对象,Rows返回行数。跟PL/SQL有点显示不一样而已。下面的NOTE只是些说明。再下面是乱码部分,主要是统计信息。
recursive calls: 调用了其它SQL数量
db block gets: 修改了多少个块
consistent gets: 内存读次数
physical reads: 物理读次数
redo size: 产生多少日志量
bytes sent via .. to client: 给客户发送多少字节;
bytes recevied via.. from client: 从客户收到多少字节;
... roundtrips to/from client: 不清楚;
sorts memory: 内存排序多少次;
sorts disk: 磁盘排序多少次;
rows processed: 共处理了多少行;
1.3 通过SQL语句获得
假如你没有工具支持的话,只有通过IP端口和协议跟数据库打交道,该如何获取呢?
先使用命令 生成执行计划:explain plan for
explain plan for select * from shark_objects;
然后查看当前执行计划:
select * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
Plan hash value: 2850217550
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 91121 | 17M| 338 (1)| 00:00:05 |
| 1 | TABLE ACCESS FULL| SHARK_OBJECTS | 91121 | 17M| 338 (1)| 00:00:05 |
-----------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)
2 获取真实的执行计划
What Fuck ! 上面说了那么多,难道不是真实的吗?
上面 SQL都没有运行的,都是评估的执行计划而已。存在于PLAN_TABLE这个表。而真实的执行计划存放在V$SQL_PLAN里。
前面使用SQLPLUS AUTOTRACE TRACEONLY 方式看到的执行计划 HASH值

在真实执行计划中是查不到的

我们重新执行一下



瞧是有的。
2.1 从v$sql_plan
上面显示的信息太多了,需要个SQL
SELECT SQL_ID,
CHILD_NUMBER,
ID,
PARENT_ID,
DEPTH,
OPERATION,
OPTIONS,
COST,
CARDINALITY,
BYTES,
IO_COST,
CPU_COST,
TEMP_SPACE,
ACCESS_PREDICATES,
FILTER_PREDICATES,
TIME,
PROJECTION,
OTHER_XML
FROM V$SQL_PLAN
WHERE SQL_ID = '4dy1xm4nxc0gf'

2.2 通过软件包获得
select * from table(dbms_xplan.display_cursor('4dy1xm4nxc0gf','0','ALL'));
会显示下面大量的信息,基本上跟SQLPLUS差不多显示方式
PLAN_TABLE_OUTPUT
SQL_ID 4dy1xm4nxc0gf, child number 0
-------------------------------------
insert into wrh$_system_event (snap_id, dbid, instance_number,
event_id, total_waits, total_timeouts, time_waited_micro,
total_waits_fg, total_timeouts_fg, time_waited_micro_fg) select
:snap_id, :dbid, :instance_number, event_id, total_waits,
total_timeouts, time_waited_micro, total_waits_fg,
total_timeouts_fg, time_waited_micro_fg from v$system_event order
by event_id
Plan hash value: 854978109
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | | | 1 (100)| |
| 1 | LOAD TABLE CONVENTIONAL | | | | | |
| 2 | SORT ORDER BY | | 1 | 169 | 1 (100)| 00:00:01 |
| 3 | NESTED LOOPS | | 1 | 169 | 0 (0)| |
|* 4 | FIXED TABLE FULL | X$KSLED | 1 | 39 | 0 (0)| |
|* 5 | FIXED TABLE FIXED INDEX| X$KSLEI (ind:1) | 1 | 130 | 0 (0)| |
----------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$5C160134
4 - SEL$5C160134 / D@SEL$3
5 - SEL$5C160134 / S@SEL$3
Predicate Information (identified by operation id):
---------------------------------------------------
4 - filter("D"."INST_ID"=USERENV('INSTANCE'))
5 - filter((("S"."KSLESWTS_UN">0 OR "S"."KSLESWTS_FG">0 OR "S"."KSLESWTS_BG">0)
AND "S"."KSLESEVT"="D"."INDX"))
Column Projection Information (identified by operation id):
-----------------------------------------------------------
2 - (#keys=1) "D"."KSLEDHASH"[NUMBER,22], :SNAP_ID[22], :DBID[22],
:INSTANCE_NUMBER[22], "S"."KSLESTIM_FG"[NUMBER,22],
"S"."KSLESWTS_UN"+"S"."KSLESWTS_FG"+"S"."KSLESWTS_BG"[22],
"S"."KSLESTMO_UN"+"S"."KSLESTMO_FG"+"S"."KSLESTMO_BG"[22],
"S"."KSLESTIM_UN"+"S"."KSLESTIM_FG"+"S"."KSLESTIM_BG"[22],
"S"."KSLESWTS_FG"[NUMBER,22], "S"."KSLESTMO_FG"[NUMBER,22]
3 - "D"."INDX"[NUMBER,22], "D"."INST_ID"[NUMBER,22], "D"."KSLEDHASH"[NUMBER,22],
"S"."KSLESEVT"[NUMBER,22], "S"."KSLESWTS_UN"[NUMBER,22],
"S"."KSLESTMO_UN"[NUMBER,22], "S"."KSLESTIM_UN"[NUMBER,22],
"S"."KSLESWTS_FG"[NUMBER,22], "S"."KSLESTMO_FG"[NUMBER,22],
"S"."KSLESTIM_FG"[NUMBER,22], "S"."KSLESWTS_BG"[NUMBER,22],
"S"."KSLESTMO_BG"[NUMBER,22], "S"."KSLESTIM_BG"[NUMBER,22]
4 - "D"."INDX"[NUMBER,22], "D"."INST_ID"[NUMBER,22], "D"."KSLEDHASH"[NUMBER,22]
5 - "S"."KSLESEVT"[NUMBER,22], "S"."KSLESWTS_UN"[NUMBER,22],
"S"."KSLESTMO_UN"[NUMBER,22], "S"."KSLESTIM_UN"[NUMBER,22],
"S"."KSLESWTS_FG"[NUMBER,22], "S"."KSLESTMO_FG"[NUMBER,22],
"S"."KSLESTIM_FG"[NUMBER,22], "S"."KSLESWTS_BG"[NUMBER,22],
"S"."KSLESTMO_BG"[NUMBER,22], "S"."KSLESTIM_BG"[NUMBER,22]
看懂执行计划 下面再说




