返回列表 回复 发帖

关于explain plan

在pl/sql developer和toad这样的开发工具里都可以看查询语句的执行计划,
但是怎么看执行计划的结果呢?我不知道都代表什么含义,又怎样来改进查询语句。
例如
附件: 您所在的用户组无法下载或查看附件
附件不清晰,再传一遍,希望大家帮忙。
附件: 您所在的用户组无法下载或查看附件
还是不怎么清晰,可以保存下来看。
还有我在google 上查了一下关于explain plan,其中主要说了auto trace,我又不很明白了,explain plan包含auto trace么,还要先建一个explain table么?

回复 #2 fret 的帖子

你认真看一下面东西,可能对你有帮助!!!
对于sql执行的小量高低.我们可以通过执行计划的信息基本上可以进行分析查看该SQL语句执行的时间.连接顺序及浪费的数据库资源等信息,从而判断该SQL语句执行的效率如何,下面就简单的介绍一下执行计划的使用
2.        Explain使用
Oracle RDBMS执行每一条SQL语句,都必须经过Oracle优化器的评估。所 以,了解优化器是如何选择(搜索)路径以及索引是如何被使用的,对优化SQL语句有很大的帮助。Explain可以用来迅速方便地查出对于给定SQL语句中的查询数据是如何得到的即搜索路径(我们通常称为Access Path)。从而使我们选择最优的查询方式达到最大的优化效果。
2.1.        安装
要使用执行计划首先需要执行相应的脚本。
使用Explain工具需要创建Explain_plan表,这必须先进入相关应用表、视图和索引的所有者的帐户内。Oracle的介质中包含有执行此项工作的SQL源程序,例如:
ORA_RDBMS: XPLAINPL.SQL (VMS)
$ORACLE_HOME/rdbms/admin/utlxplan.sql (UNIX)
该脚本后会生成一个表这个程序会创建一个名为plan_table的表,表结构如下:
我们简单的介绍一下主要的字段含义:
字段名        字段类型        含义
STATEMENT_ID        VARCHAR2(30)        explain PLAN 语句中所指定的最优STATEMENT_ID 参数值, 如果在EXPLAN PLAN语句中没有使用SET STATEMENT_ID,那么此值会被设为NULL。   
REMARKS        VARCHAR2(80)        与被解释规划的各步骤相关联的注释最长可达80 字节
OPERATION        VARCHAR2(30)        各步骤所执行内部操作的名称在某条语句所产生的第一行中该列的可能取值如下DELETE STATEMENT INSERT STATEMENT SELECT STATEMENT UPDATE STATEMENT
OPTIONS        VARCHAR2(30)        对OPERATION 列中所描述操作的变种
OBJECT_NODE        VARCHAR2(128)        用于访问对象的数据库链接database link 的名称对于使用并行执行的本地查询该列能够描述操作中输出的次序
OBJECT_OWNER        VARCHAR2(30)        对于包含有表或索引的架构schema 给出其所有者的名称
OBJECT_NAME        VARCHAR2(30)        表或索引的名称
OBJECT_INSTANCE        INTEGER        根据对象出现在原始original 语句中的次序所给出的相应次序编号就原始的语句文本而论其处理顺序为自左至右自外向内景象扩张view
OBJECT_TYPE        VARCHAR2(30)        用于提供对象描述性信息的修饰符例如索引的NON-UNIQUE
OPTIMIZER        VARCHAR2(255)        当前优化程序的模式
ID        INTEGER        分配给执行规划各步骤的编号
PARENT_ID        INTEGER        对ID 步骤的输出进行操作的下一个执行步骤的ID
POSITION        INTEGER        对于具有相同PARENT_ID 的步骤其相应的处理次序
COST        INTEGER        根据优化程序的基于开销的方法所估计出的操作开销值对于使用基于规则方法的语句该列为空该列值没有特定的测量单位它只是一个用于比较执行规划开销大小的权重值
CARDINALITY        INTEGER        根据基于开销的方法对操作所访问行数的估计值
BYTES        INTEGER        根据基于开销的方法对操作所访问字节的估计

2.2.        使用
2.2.1.        常规使用
常规使用语法:
explain PLAN [ SET STATEMENT_ID [=] < string literal > ]
[ INTO < table_name > ]
FOR < sql_statement >
其中:
STATEMENT_ID是一个唯一的字符串,把当前执行计划与存储在同一PLAN表中的其它执行计划区别开来。
TABLE_NAME是plan表名,它结构如前所示,你可以任意设定这个名称。
SQL_STATEMENT是真正的SQL语句。
如:
SQL> explain plan set statement_id='test1' for  
  2     SELECT a.soctermbegin,
  3            a.soctermend,
  4            a.dealserialno,
  5            a.levydataid,
  6            a.dealtotal,
  7            e.categoryitemcode,
  8            row_number() over(PARTITION BY a.levydataid ORDER BY 1) AS theRow
  9       FROM tb_soc_packdealdata   a,
10            tb_Lvy_TaxDataBillMap c,
11            Tb_lvy_BillData       d,
12            tb_soc_levydetaildata e
13      WHERE a.levydataid = c.datafrompointer(+)
14        AND c.billdataid = d.billdataid(+)
15        AND a.levydataid = e.levydataid
16        AND a.packdealstatuscode = '10'
17        AND (a.datastatus <> '9' OR a.datastatus is NULL)
18        AND (d.billstatus IS NULL OR
19            (d.billstatus <> '2' AND d.billstatus <> '8'))
20        AND a.Insurcode = '6010952'
21  ;
Explained
执行下面语句就可以查看该语句执行的执行计划:
SQL> SELECT A.OPERATION,OPTIONS,OBJECT_NAME,OBJECT_TYPE,ID,PARENT_ID
  2  FROM PLAN_TABLE  a
  3  WHERE STATEMENT_ID='test1'
  4  ORDER BY Id;
OPERATION        OPTIONS        OBJECT_NAME                    OBJECT_TYPEID  PARENT_ID
---------------- --------------------------------------------- ------------- ----------
SELECT STATEMENT                                                           0
WINDOW           SORT                                                      1          0
FILTER                                                                     2          1
NESTED LOOPS     OUTER                                                     3          2
NESTED LOOPS     OUTER                                                     4          3
NESTED LOOPS                                                               5          4
TABLE ACCESS     FULL           TB_SOC_PACKDEALDATA                        6          5
TABLE ACCESS     BY INDEX ROWID TB_SOC_LEVYDETAILDATA                      7          5
INDEX            RANGE SCAN     IND_DATAID_LEVSOC              NON-UNIQUE  8          7
TABLE ACCESS     BY INDEX ROWID TB_LVY_TAXDATABILLMAP                      9          4
INDEX            RANGE SCAN     TBLVYTAXDATABIL_DATAFROMPOINTE NON-UNIQUE 10          9
TABLE ACCESS     BY INDEX ROWID TB_LVY_BILLDATA                           11          3
INDEX            UNIQUE SCAN    TBLVYBILLDATA_BILLDATAID       UNIQUE   
2.2.2.        自动显示使用
在SQLPLUS中自动跟踪显示执行计划及相关信息
SQL>set timing on  --显示执行时间
SQL>set autorace on �C显示执行计划
SQL>set autorace on �C显示执行计划
SQL>set autotrace traceonly �C只显示执行计划即不显示查询出来的数据
设置完毕后执行SQL语句就会显示执行计划信息及相应的统计信息(需要设置显示该选项)
SQL> select nvl(sum(t.taxdue), 0)
  2             from tb_lvy_sbzs100 t, tb_lvy_declaredoc a, tb_lvy_declaredoc b
  3            where a.dossiercode = 'SB02041108'
  4              and a.pages = 123
  5              and a.remarkid = b.remarkid
  6              AND A.REMARKID IS NOT NULL
  7              and b.declaredocid = t.declaredocid;
NVL(SUM(T.TAXDUE),0)
--------------------
                   0
已用时间:  00: 00: 04.07
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=6 Card=1 Bytes=110)
   1    0   SORT (AGGREGATE)
   2    1     NESTED LOOPS (Cost=6 Card=1 Bytes=110)
   3    2       MERGE JOIN (CARTESIAN) (Cost=4 Card=1 Bytes=74)
   4    3         TABLE ACCESS (FULL) OF 'TB_LVY_SBZS100' (Cost=2 Card =1 Bytes=31)
   5    3         BUFFER (SORT) (Cost=2 Card=1 Bytes=43)
   6    5           TABLE ACCESS (FULL) OF 'TB_LVY_DECLAREDOC' (Cost=2 Card=1 Bytes=43)
   7    2       TABLE ACCESS (BY INDEX ROWID) OF 'TB_LVY_DECLAREDOC' (Cost=2 Card=1 Bytes=36)
   8    7         INDEX (UNIQUE SCAN) OF 'TBLVYDECLAREDOC_DECLAREDOCID' (UNIQUE)
Statistics
----------------------------------------------------------
          0  recursive calls --循环递归次数
          0  db block gets―请求的数据块在buffer能满足的个数
       6675  consistent gets --逻辑IO用于读表并计算行数, 数据请求总数在回滚段Buffer中
         45  physical reads �C从磁盘读到Buffer Cache数据块数量
          0  redo size �C产生的redo日志大小
        217  bytes sent via SQL*Net to client
        276  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          1  rows processed
SQL>
如果6675  consistent gets --逻辑IO用于读表并计算行数, 数据请求总数在回滚段Buffer中
45        physical reads �C从磁盘读到Buffer Cache数据块数量
的数值比较小则该语句对对数据库的性能比较高。

2.2.3.        PL/SQL和TOAD中使用
如果在PL/SQL中使用选择要查询语句显示执行计划,则只需要SQL WINDOWS 窗口里面输入要查询的SQL语句,然后选择按键F5或者在菜单TOOLS�D�D>Explain Plan 菜单按键就可以在执行计划窗口查看该语句的执行计划。
在TOAD语句中在执行当前的SQL窗口中选择下方的Explain PlanTAB页即可以查看要执行语句的执行计划信息。
2.3.        限制
虽然任何SQL语句都可以用explain解释,但对于没有查询的INSERT,UPDATE,DELETE操作来说,这个工具并没有太大的用处。没有子查询的INSERT操作不会创建执行计划,但没有WHERE子句或子查询的UPDATE和DELETE操作会创建执行计划,因为这些操作必须先找出所要的记录。
另外,如果你在SQL语句中使用其它类型如sequence等,explain也能揭示它的用法。
explain真正的唯一的限制是用户不能去解释其它用户的表,视图,索引或其它类型,用户必须是所有被解释事物的所有者,如果不是所有者而只有select权限,explain会返回一个错误。
如果你在SQL/Plus里面
你可以使用
Set Autotrace trance on
your sql statement;
执行之后下面将显示
plan
在这里你将看到你的sql语句执行情况,一般来说我们都比较关注他是否进行了全表扫描。如果是进行了全表扫描的话你就需要检查是那个条件发生了全表扫描,那个你对该字段建立索引就可以了。
在PL/SQL developer里面应该是按F5吧
关注中.我让一个DBA来看一下.
2005年4月发起成立ERP100.com社区。希望更多的朋友能够融入到ERP100这个大家庭。
努力值相关制度请参考http://bbs.erp100.com/thread-29183-1-1.html
个人空间:http://zonghengsihai.erp100.com
联系方式:huwanjun@baidu.com 13911575376 QQ:27675401
行业:互联网
模块:财务,人力资源,订单,合同,预算,BI(Discoverer)。
主要工作:需求分析,系统设计,项目管理,部门协调。
技术:pl/sql java Oracle 等
所在公司:百度(中国)有限公司 www.baidu.com (2004年6月~至今)
工作地点:北京
关于explain Plan,牵扯到很多PLSQL性能优化方面的东西,楼上的版主谈了很多使用的方法的问题,具体怎么用好这个工具还牵扯到很多Oracle 性能优化的知识,比如说Cost Based Optimize,Rule Based Optimize ,index 等等。如果楼主能参考一下这方面的书籍,可能会有更大的帮助。
原帖由 Richard 于 2006-9-11 10:54 AM 发表
如果你在SQL/Plus里面
你可以使用
Set Autotrace trance on
your sql statement;
执行之后下面将显示
plan
在这里你将看到你的sql语句执行情况,一般来说我们都比较关注他是否进行了全表扫描。如果是进行了 ...
我看了很多贴子上都说用sql plus,然后set autotrace on,但是我用toad的话,还要设置set autotrace on么?
我在toad里看到的explain plan 和在sql plus里设置set autotrace on,是一样的么?

[ 本帖最后由 fret 于 2006-9-11 11:13 AM 编辑 ]
在pl/sql developer里面你可以new --->query输入你sql代码,然后点击工具栏里面的工具--->explain plan(或者代码写后直接按F5)你就可以查看你的这段代码将要扫描那些表,可能会读取多少次的物理数据等信息,至于你想如何优化你的sql语句,我建议你先看看Tonychu的帖子,这里我给一个简单的基于规则的优化查询,原来的语句如下 select t.* from richard t where t.name = 'Richard',你做基于规则的优化的时候可以这么写select /*+Rule*/ t.* from richard t where t.name = 'Richard'就好

有空去看看这个连接,这个上面说的很清楚!

谢谢大家
返回列表