[20161216]toad下显示真实的执行计划.txt

[20161216]toad下显示真实的执行计划.txt

--大家都应该知道使用explain plan看执行计划,有时候显示的执行计划不是真实的执行计划.现在我虽然使用它看,仅仅作为参考.
--昨天看链接:
http://www.toadworld.com/platforms/oracle/b/weblog/archive/2016/12/13/toad-explain-plan-tip-returning-actual-sql-execution-explain-plan

--才知道toad下如何在sql编辑界面上显示真实的执行计划.

--仅仅在执行计划上点击右键,勾上"load cached plan if possible" 就ok了.我自己写一个例子测试看看.

1.环境:
SCOTT@book> @ &r/ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

create table t as select rownum id ,lpad('x',100,'x') name ,lpad('1',1) flag from dual connect by level<=1e5;
update t set flag='0' where id=1e5;
commit ;
create index i_t_flag on t(flag);

SCOTT@book> execute sys.dbms_stats.gather_table_stats ( OwnName => '',TabName => 't',Estimate_Percent => NULL,Method_Opt => 'FOR ALL COLUMNS SIZE 1 for columns flag size 4',Cascade => True ,No_Invalidate => false)
PL/SQL procedure successfully completed.

--在flag字段上建立直方图.

2.测试:
Select /*+ BIND_AWARE */ * from t where flag=:x;

--实际情况下带入'0','1',两者执行计划不一样.而在toad下使用explain plan看就是全表扫描.
--先带入'0'测试看看.再sql下执行看看.

SCOTT@book> alter system flush shared_pool;
System altered.

SCOTT@book> variable x varchar2(1)
SCOTT@book> exec :x := '0';
PL/SQL procedure successfully completed.

SCOTT@book> SELECT /*+ BIND_AWARE */ * from t where flag=:x;
        ID NAME                                     F
---------- ---------------------------------------- -
    100000 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 0
           xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
           xxxxxxxxxxxxxxxxxxxx

SCOTT@book> @ &r/dpc ''  ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  7739acusdmc6c, child number 0
-------------------------------------
SELECT /*+ BIND_AWARE */ * from t where flag=:x
Plan hash value: 120143814
-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name     | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |        |       |     2 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| T        |      1 |   108 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | I_T_FLAG |      1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1 / T@SEL$1
   2 - SEL$1 / T@SEL$1
Peeked Binds (identified by position):
--------------------------------------
   1 - (VARCHAR2(30), CSID=852): '0'
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("FLAG"=:X)

3.toad下查看,修改display mode 改成 dbms_xplan,这样不用帖图.
SQL_ID  7739acusdmc6c, child number 0
-------------------------------------
SELECT /*+ BIND_AWARE */ * from t where flag=:x
Plan hash value: 120143814
-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name     | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |        |       |     2 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| T        |      1 |   108 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | I_T_FLAG |      1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1 / T@SEL$1
   2 - SEL$1 / T@SEL$1
Outline Data
-------------
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
      DB_VERSION('11.2.0.4')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      INDEX_RS_ASC(@"SEL$1" "T"@"SEL$1" ("T"."FLAG"))
      END_OUTLINE_DATA
  */
Peeked Binds (identified by position):
--------------------------------------
   1 - (VARCHAR2(30), CSID=852): '0'
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("FLAG"=:X)
 
Column Projection Information (identified by operation id):
-----------------------------------------------------------
 
   1 - "T"."ID"[NUMBER,22], "T"."NAME"[VARCHAR2,100], "FLAG"[VARCHAR2,1]
   2 - "T".ROWID[ROWID,10], "FLAG"[VARCHAR2,1]
 
Note
-----
   - Warning: basic plan statistics not available. These are only collected when:
       * hint 'gather_plan_statistics' is used for the statement or
       * parameter 'statistics_level' is set to 'ALL', at session or system level
 
--//可以发现执行计划走索引.
--//修改SELECT 为sELECT,再看执行计划,看到的执行计划如下:
Plan hash value: 1601196873
---------------------------------------------------------------------------
| Id  | Operation         | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |  50000 |  5273K|   435   (1)| 00:00:06 |
|*  1 |  TABLE ACCESS FULL| T    |  50000 |  5273K|   435   (1)| 00:00:06 |
---------------------------------------------------------------------------
 
--很明显这个执行计划可能是不真实的.

3.另外我也发现问题,如果你跟踪toad操作,可以发现

declare
  v_ignore raw(100);
  v_oldhash number;
  v_hash number;
begin
  v_hash := dbms_utility.get_sql_hash(:SQLText || chr(0), v_ignore, v_oldhash);
  :outHash := v_hash;
end;

SQLText=['sELECT /*+ BIND_AWARE */ * from t where flag=:x']
outHash=[0.334866302e+010]

Elapsed time: 0.003
--------------------------------------------------------------------------------
Timestamp: 2016/12/16 11:33:09

Select *
from v$sql_plan
Where hash_value = '3348663027'
and child_number =0
order by id

sqlhv=['3348663027']
cn=[0]

Elapsed time: 0.005

explain plan set statement_id='Administrator:121616113309' into SYS.PLAN_TABLE$ For sELECT /*+ BIND_AWARE */ * from t where flag=:x
Elapsed time: 0.005

--它仅仅查询v$sql_plan child_number =0的是否存在,有一些情况child_number =0是已经无效的执行计划,甚至不存在的执行计划.
--这样依旧调用explain plan.这个问题也存在于SGA TRACE的界面上.我一直希望有一个下拉列表,让dba选择对应的child_number.

4.还有这个测试我还发现toad界面下,提示BIND_AWARE无效.
你可以发现在toad下执行,带入变量'0',选择的执行计划依旧是全表扫描.

--//修改flag大写,在toad下执行,变量'0'.
sELECT /*+ BIND_AWARE */ * from t where FLAG=:x;

SCOTT@book> select sql_id,sql_text,executions  from v$sqlarea where upper(sql_text) like 'SELECT%BIND_AWARE%' and upper(sql_text) not like '%SQL_TEXT%';
SQL_ID        SQL_TEXT                                                     EXECUTIONS
------------- ------------------------------------------------------------ ----------
3bsyf7a6jz1py SELEct /*+ BIND_AWARE */ * from t where flag=:x                       3
bh4qquz7sm25k sELECT /*+ BIND_AWARE */ * from t where FLAG=:x                       1
7739acusdmc6c SELECT /*+ BIND_AWARE */ * from t where flag=:x                       1

--看看sql_id='bh4qquz7sm25k'执行计划.

SCOTT@book> @ &r/dpc bh4qquz7sm25k  ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  bh4qquz7sm25k, child number 0
-------------------------------------
sELECT /*+ BIND_AWARE */ * from t where FLAG=:x
Plan hash value: 1601196873
---------------------------------------------------------------------------
| Id  | Operation         | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |        |       |   435 (100)|          |
|*  1 |  TABLE ACCESS FULL| T    |  50000 |  5273K|   435   (1)| 00:00:06 |
---------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1 / T@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("FLAG"=:X)

--选择的是全表扫描.估计和工具显示返回行数有关,不过我打上auto trace测试结果也一样.不知道为什么无效.
--然后在sqlplus执行相同的语句:
SCOTT@book> sELECT /*+ BIND_AWARE */ * from t where FLAG=:x;
        ID NAME                                     F
---------- ---------------------------------------- -
    100000 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 0
           xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
           xxxxxxxxxxxxxxxxxxxx

SCOTT@book> @ &r/dpc ''  ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  bh4qquz7sm25k, child number 1
-------------------------------------
sELECT /*+ BIND_AWARE */ * from t where FLAG=:x

Plan hash value: 120143814

-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name     | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |        |       |     2 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| T        |      1 |   108 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | I_T_FLAG |      1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1 / T@SEL$1
   2 - SEL$1 / T@SEL$1
Peeked Binds (identified by position):
--------------------------------------
   1 - (VARCHAR2(30), CSID=852): '0'
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("FLAG"=:X)

SCOTT@book> @ &r/share bh4qquz7sm25k
SQL_TEXT                       = sELECT /*+ BIND_AWARE */ * from t where FLAG=:x
SQL_ID                         = bh4qquz7sm25k
ADDRESS                        = 000000007BCEEFB8
CHILD_ADDRESS                  = 000000007CA23160
CHILD_NUMBER                   = 0
REASON                         = <ChildNode><ChildNumber>0</ChildNumber><ID>45</ID><reason>NLS Settings(0)</reason>
                                 <size>2x4</size><SessionLengthSemantics>0</SessionLengthSemantics><CursorLengthSemantics>0
                                 </CursorLengthSemantics></ChildNode>
--------------------------------------------------
SQL_TEXT                       = sELECT /*+ BIND_AWARE */ * from t where FLAG=:x
SQL_ID                         = bh4qquz7sm25k
ADDRESS                        = 000000007BCEEFB8
CHILD_ADDRESS                  = 000000007BD006A8
CHILD_NUMBER                   = 1
LANGUAGE_MISMATCH              = Y
REASON                         =
--------------------------------------------------
PL/SQL procedure successfully completed.

--不知道为什么,以后研究看看把.
总之:
这个功能有比没有好,当然toad应该改进更好.

时间: 2024-08-02 07:23:50

[20161216]toad下显示真实的执行计划.txt的相关文章

如何获取真实的执行计划

 验证 explain plan命令   与  set autotrace命令  是否为真实执行计划       0  CONN /AS SYSDBA;              1  create table t1 as select * from dba_objects;           2  insert into t1 select * from t1;         3   commit;         4   select count(1) from t1;         

[20120104]稳定一条sql语句的执行计划.txt

[20120104]稳定一条sql语句的执行计划.txt http://www.itpub.net/thread-1495845-1-1.htmlhttp://space.itpub.net/267265/viewspace-723066 ORACLE8I升级11G R2后,查询系统视图特别慢 我的测试版本:SQL> select * from v$version where rownumBANNER------------------------------------------------

[20120112]谨慎使用set autotrace traceonly查看执行计划.txt

自己经常在优化sql语句是经常使用set autotrace traceonly来优化sql语句.这样的好处是如果输出记录很多,可以不受干扰,直接查看执行计划以及执行计划的统计信息.但是在一些特殊情况要注意也许执行计划是不真实的. SQL> select * from v$version;BANNER--------------------------------------------------------------------------------Oracle Database 11g

《Oracle高性能SQL引擎剖析:SQL优化与调优机制详解》一1.2 显示执行计划

1.2 显示执行计划 我们现在知道,有三个途径可以获取查询计划:v$sql_plan.dba_hist_sql_plan和PLAN_TABLE.如果需要读取一条SQL语句的执行计划,就需要知道该条语句的SQL_ID,如果该语句存在多个游标或者执行计划,则还需要知道游标的CHILD_NUMBER或计划的哈希值(可选).而无论我们通过哪个途径来获取执行计划,显示方式主要是两种:语句查询和包DBMS_XPLAN显示. 1.2.1 通过查询语句显示计划 通过查询语句从一些视图里读出执行计划并作格式化输出

8i下sort*排序大小以及执行计划的问题?

最近看8i下sort设置对执行计划的影响,发现一些奇特的现象,特此写下来: 最近看8i下sort设置对执行计划的影响,发现一些奇特的现象,特此写下来: a.sql: SELECT a.name, b.value FROM v$statname a, v$mystat b WHERE a.statistic# = b.statistic# AND a.name like '%ga %' / b.sql: SELECT "UNDRUG_INFO"."UNDRUG_CODE&quo

Oracle中获取执行计划的几种方法分析

以下是对Oracle中获取执行计划的几种方法进行了详细的分析介绍,需要的朋友可以参考下   1. 预估执行计划 - Explain PlanExplain plan以SQL语句作为输入,得到这条SQL语句的执行计划,并将执行计划输出存储到计划表中. 首先,在你要执行的SQL语句前加explain plan for,此时将生成的执行计划存储到计划表中,语句如下: explain plan for SQL语句然后,在计划表中查询刚刚生成的执行计划,语句如下: select * from table(

一个执行计划异常变更引发的Oracle性能诊断优化

最近有一个OLTP应用使用的Oracle数据库突然出现性能问题,DBA发现有一些delete语句执行时间骤长,消耗大量系统资源,导致应用响应时间变长积Q.   辅助信息: 应用已经很久未做过更新上线了. 据开发人员反馈,从之前的应用日志看,未出现处理时间逐步变长的现象. 这是一套RAC+DG的环境,11g的版本. 这次突然出现大量执行时间超长的SQL语句,是一条删除语句,delete from table where key1=:1 and key2=:2 and ...(省略此案例不会用到的其

ORACLE数据库查看执行计划

基于ORACLE的应用系统很多性能问题,是由应用系统SQL性能低劣引起的,所以,SQL的性能优化很重要,分析与优化SQL的性能我们一般通过查看该SQL的执行计划,本文就如何看懂执行计划,以及如何通过分析执行计划对SQL进行优化做相应说明. 一.什么是执行计划(explain plan) 执行计划:一条查询语句在ORACLE中的执行过程或访问路径的描述. 二.如何查看执行计划 1: 在PL/SQL下按F5查看执行计划.第三方工具toad等. 很多人以为PL/SQL的执行计划只能看到基数.优化器.耗

ORACLE数据库查看执行计划的方法_oracle

一.什么是执行计划(explain plan) 执行计划:一条查询语句在ORACLE中的执行过程或访问路径的描述. 二.如何查看执行计划 1: 在PL/SQL下按F5查看执行计划.第三方工具toad等. 很多人以为PL/SQL的执行计划只能看到基数.优化器.耗费等基本信息,其实这个可以在PL/SQL工具里面设置的.可以看到很多其它信息,如下所示 2: 在SQL*PLUS(PL/SQL的命令窗口和SQL窗口均可)下执行下面步骤 复制代码 代码如下: SQL>EXPLAIN PLAN FOR SEL