新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正
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
文章结束给大家分享下程序员的一些笑话语录: 一个合格的程序员是不会写出 诸如 “摧毁地球” 这样的程序的,他们会写一个函数叫 “摧毁行星”而把地球当一个参数传进去。