执行计划信息Oracle 执行计划总结
新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正
1 看查Oracle执行筹划的几种方法
1.1 通过PL/SQL Dev工具
1、直接File->New->Explain Plan Window,在窗口中执行sql可以看查筹划结果。其中,Cost表现cpu的耗消,位单为n%,Cardinality表现执行的行数,等价Rows。
2、先执行 EXPLAIN PLAN FOR select * from tableA where paraA=1,再 select * from table(DBMS_XPLAN.DISPLAY)便可以看到oracle的执行筹划了,看到的结果和1中的一样,所以应用工具的时候推荐应用1方法。
注意:PL/SQL Dev工具的Command window中不持支set autotrance on的命令。还有应用工具方法看查筹划看到的信息不全,有些时候我们要需sqlplus的持支。
1.2 通过sqlplus
1.最简略的办法
Sql> set autotrace on
Sql> select * from dual;
执行完句语后,会显示explain plan 与统计信息。
这个句语的长处就是它的点缺,这样在用该方法看查执行间时较长的sql句语时,要需等待该句语执行胜利后,才返回执行筹划,使化优的期周大大增加。如果不想执行句语而只是想失掉执行筹划可以用采:
Sql> set autotrace traceonly
这样,就只会列出执行筹划,而不会真正的执行句语,大大减少了化优间时。虽然也列出了统计信息,但是因为没有执行句语,所以该统计信息没有效处,如果执行该句语时到遇错误,解决方法为:
(1)在要分析的户用下:
Sqlplus > @ ?
dbmsadminutlxplan.sql
(2) 用sys户用登岸
Sqlplus > @ ?sqlplusadminplustrce.sql
Sqlplus > grant plustrace to user_name;
- - user_name是下面所说的分析户用
2.用explain plan命令
(1) sqlplus > explain plan for select * from testdb.myuser
(2) sqlplus > select * from table(dbms_xplan.display);
下面这2种方法只能为在本话会中正在行运的句语生产执行筹划,即我们要需经已知道了哪条句语行运的效率很差,我们是有的目只对这条SQL句语去化优。其实,在很多况情下,我们只会听一个客户怨抱说在现统系行运很慢,而我们不知道是哪个SQL起引的。此时有很多现成的句语可以找出耗消资源比较多的句语,如:
SELECT ADDRESS, substr(SQL_TEXT,1,20) Text, buffer_gets, executions,
buffer_gets/executions AVG FROM v$sqlarea
WHERE executions>0 AND buffer_gets > 100000 ORDER BY 5;
ADDRESS TEXT BUFFER_GETS EXECUTIONS AVG
-------- ---------------------------------------- ----------- ---------- ------------------------------------------------------------
66D83D64 select t.name, (sel 421531 60104 7.01336017
66D9E8AC select t.schema, t.n 1141739 2732 417.913250
66B82BCC select s.synonym_nam 441261 6 73543.5
从而对找出的句语停止进一步化优。当然我们还可认为一个正在行运的话会中行运的全部SQL句语成生执行筹划,这要需对该话会停止跟踪,生产trace件文,然后对该件文用tkprof序程格式化一下,种这失掉执行筹划的方法很有效,因为它含包其它额外信息,如SQL句语执行的每一个阶段(如Parse、Execute、Fetch)分离耗消的各个资源况情(如CPU、DISK、elapsed等)。
1.3 启用SQL_TRACE跟踪全部后台进程动活:
全局参数设置: .OracleHome/admin/SID/pfile中指定: SQL_TRACE = true (10g)
前当session中设置:
SQL> alter session set SQL_TRACE=true;
SQL> select * from dual;
SQL> alter session set SQL_TRACE=false;
对其他户用停止跟踪设置:
SQL> select sid,serial#,username from v$session where username='XXX';
SID SERIAL# USERNAME
------ ---------- ------------------
127 31923 A
128 54521 B
开启跟踪:SQL> exec dbms_system.set_SQL_TRACE_in_session(127,31923,true);
关闭跟踪:SQL> exec dbms_system.set_SQL_TRACE_in_session(127,31923,false);
然后应用oracle自带的tkprof命令行工具格式化跟踪件文。
1.4 应用tkprof格式化跟踪件文:
一般,一次跟踪可以分为以下几步:
1、界定要需跟踪的目标范围,并应用当适的命令启用所需跟踪。
2、经过一段间时后,停止跟踪。此时该应生产了一个跟踪结果件文。
3、找到跟踪件文,并对其停止格式化,然后读阅或分析。
--应用一下SQL找到前当session的跟踪件文:
SELECT d.value|| '/' ||lower(rtrim(i.instance, chr( 0 )))|| '_ora_' ||p.spid|| '.trc'trace_file_name
from
( select p.spid from v$mystat m,v$session s, v$process p
where m.statistic# = 1 and s.sid = m.sid and p.addr = s.paddr) p,
( select t.instance from v$thread t,v$parameter v
where v.name = 'thread' and (v.value = 0 or t.thread# = to_number(v.value))) i,
( select value from v$parameter where name = 'user_dump_dest' ) d;
-- 其它户用的 session
SELECT d.value|| '/' ||lower(rtrim(i.instance, chr( 0 )))|| '_ora_' ||p.spid|| '.trc'trace_file_name
from
( select p.spid from v$session s, v$process p
where s.sid= '27' and s. SERIAL#= '30' and p.addr = s.paddr) p,
( select t.instance from v$thread t,v$parameter v
where v.name = 'thread' and (v.value = 0 or t.thread# = to_number(v.value))) i,
( select value from v$parameter where name = 'user_dump_dest' ) d;
--查找后应用tkprof命令,将TRACE件文格式为到D盘的explain_format.txt件文中
SQL> $tkprof d:/oracle/admin/FZLGFM/udump/fzlgfm_ora_3468.trc d:/explain_format.txt
件文容内大致如下
TKPROF: Release 9.2.0.1.0 - Production on 星期二 4月 20 13:59:20 2010
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Trace file: d:/oracle/admin/FZLGFM/udump/fzlgfm_ora_3468.trc
Sort options: default
********************************************************************************
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
********************************************************************************
alter session set events '10046 trace name context forever, level 8'
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 0 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 1 0.00 0.00 0 0 0 0
Misses in library cache during parse: 0
Misses in library cache during execute: 1
Optimizer goal: CHOOSE
Parsing user id: SYS
2 如何看懂ORACLE执行筹划
2.1 什么是执行筹划
An explain plan is a representation of the access path that is taken when a query is executed within Oracle.
2.2 如何问访数据
At the physical level Oracle reads blocks of data. The smallest amount of data read is a single Oracle block, the largest is constrained by operating system limits (and multiblock i/o). Logically Oracle finds the data to read by using the following methods:
Full Table Scan (FTS) --全表扫描
Index Lookup (unique & non-unique) --引索扫描(一唯和非一唯)
Rowid --物理行id
2.3 执行筹划层次系关
When looking at a plan, the rightmost (ie most inndented) uppermost operation is the first thing that is executed. --用采最右最上先最执行的准则看层次系关,在统一级如果某个作动没有子ID就先最执行
2.3.1 例子讲解
Execution Plan
----------------------------------------------------------
0 **SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=8 Bytes=248)
1 0 **HASH JOIN (Cost=3 Card=8 Bytes=248)
2 1 ****TABLE ACCESS (FULL) OF 'DEPT' (Cost=1 Card=3 Bytes=36)
3 1 ****TABLE ACCESS (FULL) OF 'EMP' (Cost=1 Card=16 Bytes=304)
侧左的两排数据,面前的是序列号ID,面后的是对应的PID(父ID)。
A shortened summary of this is:
Execution starts with ID=0: SELECT STATEMENT but this is dependand on it's child objects
So it executes its first child step: ID=1 PID=0 HASH JOIN but this is dependand on it's child objects
So it executes its first child step: ID=2 PID=1 TABLE ACCESS (FULL) OF 'DEPT'
Then the second child step: ID=3 PID=2 TABLE ACCESS (FULL) OF 'EMP'
Rows are returned to the parent step(s) until finished
2.4 表问访方法
2.4.1 Full Table Scan (FTS) 全表扫描
In a FTS operation, the whole table is read up to the high water mark (HWM). The HWM marks the last block in the table that has ever had data written to it. If you have deleted all the rows then you will still read up to the HWM. Truncate resets the HWM back to the start of the table. FTS uses multiblock i/o to read the blocks from disk. --全表扫描模式下会读数据到表的高水位线(HWM即表现表曾扩展的最后一个数据块),读取度速依赖于Oracle初始化参数db_block_multiblock_read_count(我得觉该应这样翻译:FTS扫描会使表应用上升到高水位(HWM),HWM识标了表最后写入数据的块,如果你用DELETE删除了全部的数据表仍然处于高水位(HWM),只有效TRUNCATE才能使表回归,FTS应用多IO从盘磁读取数据块).
2.4.2 Index Lookup 引索扫描
There are 5 methods of index lookup:
index unique scan --引索一唯扫描
Method for looking up a single key value via a unique index. always returns a single value, You must supply AT LEAST the leading column of the index to access data via the index.
eg:SQL> explain plan for select empno,ename from emp where empno=10;
index range scan --引索局部扫描
Index range scan is a method for accessing a range values of a particular column. AT LEAST the leading column of the index must be supplied to access data via the index. Can be used for range operations (e.g. > < <> >= <= between) .
eg:SQL> explain plan for select mgr from emp where mgr = 5;
index full scan --引索全局扫描
Full index scans are only available in the CBO as otherwise we are unable to determine whether a full scan would be a good idea or not. We choose an index Full Scan when we have statistics that indicate that it is going to be more efficient than a Full table scan and a sort. For example we may do a Full index scan when we do an unbounded scan of an index and want the data to be ordered in the index order.
eg: SQL> explain plan for select empno,ename from big_emp order by empno,ename;
index fast full scan --引索倏地全局扫描,不带order by况情下常产生
Scans all the block in the index, Rows are not returned in sorted order, Introduced in 7.3 and requires V733_PLANS_ENABLED=TRUE and CBO, may be hinted using INDEX_FFS hint, uses multiblock i/o, can be executed in parallel, can be used to access second column of concatenated indexes. This is because we are selecting all of the index.
eg: SQL> explain plan for select empno,ename from big_emp;
index skip scan --引索腾跃扫描,where件条列长短引索的前导列况情下常产生
Index skip scan finds rows even if the column is not the leading column of a concatenated index. It skips the first column(s) during the search.
eg:SQL> create index i_emp on emp(empno, ename);
SQL> select /*+ index_ss(emp i_emp)*/ job from emp where ename='SMITH';
2.4.3 .Rowid 物理ID扫描
This is the quickest access method available.Oracle retrieves the specified block and extracts the rows it is interested in. --Rowid扫描是最快的问访数据方法
看执行筹划时,我们的症结不是看哪个操纵先执行,哪个操纵后执行,而是症结看表之间连接的序顺(如得悉哪个为驱动表,这要需从操纵的序顺停止判断)、应用了何种型类的关联及体具的取存路径(如判断否是利用了引索)
在从执行筹划中判断出哪个表为驱动表后,根据我们的识知判断该表作为驱动表否是适合,如果不适合,对SQL句语停止改更,使化优器可以选择准确的驱动表。
3 执行筹划稳定性能带给我们什么
Oracle存在着执行筹划选择失误的可能。这也是我们经常见遇的一些象现,比如总有人说我的序程在测试数据库中跑的很好,但在产品数据库上就是跑的很差,甚至后者硬件件条比前者还好,这究竟是为什么?硬件资源、统计信息、参数设置都可能对执行筹划生产影响。由于素因太多,我们是总对来未怀着一种莫名的恐怖,我的产品数据库上线后到底跑的好不好?于是Oracle供给了一种稳定执行筹划的能力,也就是把在测试环境中的行运精良的执行筹划所生产的OUTLINES植移到产品数据库,使得执行筹划不会随着其他素因的化变而化变。
那么OUTLINES是什么呢?先要分析一个容内,Oracle供给了在SQL中应用HINTS来导引化优器生产我们想要的执行筹划的能力。这在多表连接、杂复查询中别特有效。HINTS的型类很多,可以设置化优器目标(RULE、CHOOSE、FIRST_ROWS、ALL_ROWS),可以指定表连接的序顺,可以指定应用哪个表的哪个引索等等,可以对SQL停止很多细精的控制。通过种这方法生产我们想要的执行筹划的这些HINTS,Oracle可以存储这些HINTS,我们称之为OUTLINES。通过STORE OUTLINES可以使得我们有拥当前生产同相执行筹划的能力,也就是使我们有拥了稳定执行筹划的能力。
3.1 Oracle Hints的应用
Eg: alter session enable dml parallel;
insert /*+parallel(xxxx,4) */ into xxxx select /*+parallel(a) */ * from xxx a;
Hints的体具户用请自己查询相干资料。。。。。。
http://blog.csdn.net/runming918/article/details/8900750
3.2 Oracle 集收统计更新信息
或许我们会有疑难,假如稳定了执行筹划,那还征集统计信息干嘛?这是因为几个原因成造的,首先,在现的执行筹划对于来未产生了化变的数据未必就是适合的,存在着前当的执行筹划不满足来未数据的化变后的效率,而新的统计信息的况情下所生产的执行筹划也是不并全部都理合的。那这个时候,我们可以用采新征集的统计信息,但是却对新统计信息下不良的执行筹划用采Oracle供给的执行筹划稳定性这个能力定固执行筹划,这样结合起来我们可以建立意满的高效的数据库行运环境。
我们还要需注关的一个货色,Oracle供给的dbms_stats包除了有具征集统计信息的能力,还有具把数据库中统计信息(statistics)export/import的能力,还有具只征集统计信息而使得统计信息应不于用数据库的能力(把统计信息征集到一个特定的表中而不是即立失效),在这个基础上我们就能够把统计信息export出来再import到一个测试环境中,再行运我们的应用,在测试环境中我们视察最新的统计信息会致导哪些执行筹划产生化变(DB EXPERT的Plan Version Tracer是模拟不同环境并主动检查不同环境中执行筹划化变的工具),是变好了还是变差了。我们可以把变差的这一部分在测试环境中应用hints或者利用工具(SQL EXPERT是在写重SQL这一范畴现在最强力有的工具)生产精良的执行筹划的SQL,利用这些SQL可以生产OUTLINES,然后在产品数据库应用最新的统计信息的同时植移进这些OUTLINES。
请清晰dbms_stat包的用法,体具请查阅相干资料学习。
http://blog.csdn.net/runming918/article/details/7223368
文章结束给大家分享下程序员的一些笑话语录:
一个合格的程序员是不会写出 诸如 “摧毁地球” 这样的程序的,他们会写一个函数叫 “摧毁行星”而把地球当一个参数传进去。