[20171201]关于explain plan.txt

简介: [20171201]关于explain plan.txt --//大家都应该知道使用explain plan看执行计划,有时候显示的执行计划不是真实的执行计划. --//一般不建议采用explain plan 看执行计划.

[20171201]关于explain plan.txt

--//大家都应该知道使用explain plan看执行计划,有时候显示的执行计划不是真实的执行计划.
--//一般不建议采用explain plan 看执行计划.
--//toad设计一直有一个小小缺陷,就是扫描sga时找到sql语句查询执行计划,
--//它仅仅查询v$sql_plan child_number =0的是否存在,有一些情况child_number =0是已经无效的执行计划,甚至不存在的执行计划.
--//这样依旧调用explain plan.这个问题也存在于SGA TRACE的界面上.我一直希望有一个下拉列表,让dba选择对应的child_number.
--//参考链接:http://blog.itpub.net/267265/viewspace-2130781/

--//今天我才发现explain plan每次调用实际上cursor是不共享的,有点奇怪,做一个记录.

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

SCOTT@book> show parameter cursor_sharing
NAME           TYPE   VALUE
-------------- ------ -------
cursor_sharing string EXACT

2.测试:
SCOTT@book> explain plan for select * from dept where  deptno=10;
Explained.

SCOTT@book> explain plan for select * from dept where  deptno=10;

Explained.

SCOTT@book> explain plan for select * from dept where  deptno=10;

Explained.

SCOTT@book> @ &r/dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  1xmp0v4m617j4, child number 2

explain plan for select * from dept where  deptno=10

NOTE: cannot fetch plan for SQL_ID: 1xmp0v4m617j4, CHILD_NUMBER: 2
      Please verify value of SQL_ID and CHILD_NUMBER;
      It could also be that the plan is no longer in cursor cache (check v$sql_plan)
8 rows selected.

--//这样能很快知道SQL_ID=1xmp0v4m617j4.

SCOTT@book> @ &r/share 1xmp0v4m617j4
SQL_TEXT                       = explain plan for select * from dept where  deptno=10
SQL_ID                         = 1xmp0v4m617j4
ADDRESS                        = 000000007C642498
CHILD_ADDRESS                  = 000000007C4BC188
CHILD_NUMBER                   = 0
REASON                         = <ChildNode><ChildNumber>0</ChildNumber><ID>20</ID><reason>Explain Plan
cursor(0)</reason><size>2x1</size><ctxflg_cursor>50</ctxflg_cursor><Literal_Replacement_Enabled>1</Literal_Replacement_Enabled></ChildNode><ChildNode><ChildNumber>0</ChildNumber><ID>20</ID><reason>Explain Plan
cursor(0)</reason><size>2x1</size><ctxflg_cursor>50</ctxflg_cursor><Literal_Replacement_Enabled>1</Literal_Replacement_Enabled></ChildNode>
--------------------------------------------------
SQL_TEXT                       = explain plan for select * from dept where  deptno=10
SQL_ID                         = 1xmp0v4m617j4
ADDRESS                        = 000000007C642498
CHILD_ADDRESS                  = 000000007C209728
CHILD_NUMBER                   = 1
EXPLAIN_PLAN_CURSOR            = Y
REASON                         = <ChildNode><ChildNumber>1</ChildNumber><ID>20</ID><reason>Explain Plan
cursor(0)</reason><size>2x1</size><ctxflg_cursor>50</ctxflg_cursor><Literal_Replacement_Enabled>1</Literal_Replacement_Enabled></ChildNode><ChildNode><ChildNumber>1</ChildNumber><ID>20</ID><reason>Explain Plan
cursor(0)</reason><size>2x1</size><ctxflg_cursor>50</ctxflg_cursor><Literal_Replacement_Enabled>1</Literal_Replacement_Enabled></ChildNode>
--------------------------------------------------
SQL_TEXT                       = explain plan for select * from dept where  deptno=10
SQL_ID                         = 1xmp0v4m617j4
ADDRESS                        = 000000007C642498
CHILD_ADDRESS                  = 000000007B9C68A0
CHILD_NUMBER                   = 2
EXPLAIN_PLAN_CURSOR            = Y
REASON                         = <ChildNode><ChildNumber>2</ChildNumber><ID>20</ID><reason>Explain Plan cursor(0)</reason><size>2x1</size><ctxflg_cursor>50</ctxflg_cursor><Literal_Replacement_Enabled>1</Literal_Replacement_Enabled></ChildNode>
--------------------------------------------------
PL/SQL procedure successfully completed.

--//我调用3次每次都不能共享.

3.换成绑定变量的sql语句,测试看看.

SCOTT@book> explain plan for select * from dept where  deptno=:B0;
Explained.

SCOTT@book> explain plan for select * from dept where  deptno=:B0;
Explained.

SCOTT@book> explain plan for select * from dept where  deptno=:B0;
Explained.

SCOTT@book> explain plan for select * from dept where  deptno=:B0;
Explained.

SCOTT@book> @ &r/dpc '' ''
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------
SQL_ID  4pd1ywtkkka6p, child number 3

explain plan for select * from dept where  deptno=:B0

NOTE: cannot fetch plan for SQL_ID: 4pd1ywtkkka6p, CHILD_NUMBER: 3
      Please verify value of SQL_ID and CHILD_NUMBER;
      It could also be that the plan is no longer in cursor cache (check v$sql_plan)
8 rows selected.

--//问题依旧.不过理由有点点不同.

SCOTT@book> @ &r/share 4pd1ywtkkka6p
SQL_TEXT                       = explain plan for select * from dept where  deptno=:B0
SQL_ID                         = 4pd1ywtkkka6p
ADDRESS                        = 000000007B5F3508
CHILD_ADDRESS                  = 000000007C33DDB0
CHILD_NUMBER                   = 0
REASON                         = <ChildNode><ChildNumber>0</ChildNumber><ID>20</ID><reason>Explain Plan cursor(0)</reason><size>2x1</size><ctxflg_cursor>50</ctxflg_cursor><Literal_Replacement_Enabled>1</Literal_Replacement_Enabled></ChildNode>
--------------------------------------------------
SQL_TEXT                       = explain plan for select * from dept where  deptno=:B0
SQL_ID                         = 4pd1ywtkkka6p
ADDRESS                        = 000000007B5F3508
CHILD_ADDRESS                  = 000000007D651B30
CHILD_NUMBER                   = 1
EXPLAIN_PLAN_CURSOR            = Y
REASON                         = <ChildNode><ChildNumber>1</ChildNumber><ID>20</ID><reason>Explain Plan cursor(0)</reason><size>2x1</size><ctxflg_cursor>50</ctxflg_cursor><Literal_Replacement_Enabled>1</Literal_Replacement_Enabled></ChildNode>
--------------------------------------------------
SQL_TEXT                       = explain plan for select * from dept where  deptno=:B0
SQL_ID                         = 4pd1ywtkkka6p
ADDRESS                        = 000000007B5F3508
CHILD_ADDRESS                  = 000000007CE11E78
CHILD_NUMBER                   = 2
EXPLAIN_PLAN_CURSOR            = Y
REASON                         = <ChildNode><ChildNumber>2</ChildNumber><ID>20</ID><reason>Explain Plan cursor(0)</reason><size>2x1</size><ctxflg_cursor>50</ctxflg_cursor><Literal_Replacement_Enabled>1</Literal_Replacement_Enabled></ChildNode>
--------------------------------------------------
SQL_TEXT                       = explain plan for select * from dept where  deptno=:B0
SQL_ID                         = 4pd1ywtkkka6p
ADDRESS                        = 000000007B5F3508
CHILD_ADDRESS                  = 000000007D378AE0
CHILD_NUMBER                   = 3
EXPLAIN_PLAN_CURSOR            = Y
REASON                         =
--------------------------------------------------

PL/SQL procedure successfully completed.

 

4.附上share.sql脚本:
SET  serveroutput on size  1000000;

DECLARE
   c           NUMBER;
   col_cnt     NUMBER;
   col_rec     DBMS_SQL.desc_tab;
   col_value   VARCHAR2 (4000);
   ret_val     NUMBER;
BEGIN
   c := DBMS_SQL.open_cursor;
   DBMS_SQL.parse
      (c,
       'select q.sql_text, s.*
      from v$sql_shared_cursor s, v$sql q
      where s.sql_id = q.sql_id
          and s.child_number = q.child_number
          and q.sql_id like ''&1''',
       DBMS_SQL.native
      );
   DBMS_SQL.describe_columns (c, col_cnt, col_rec);

   FOR idx IN 1 .. col_cnt
   LOOP
      DBMS_SQL.define_column (c, idx, col_value, 4000);
   END LOOP;

   ret_val := DBMS_SQL.EXECUTE (c);

   WHILE (DBMS_SQL.fetch_rows (c) > 0)
   LOOP
      FOR idx IN 1 .. col_cnt
      LOOP
         DBMS_SQL.COLUMN_VALUE (c, idx, col_value);

         IF col_rec (idx).col_name IN
               ('SQL_ID', 'ADDRESS', 'CHILD_ADDRESS', 'CHILD_NUMBER',
                'SQL_TEXT','REASON')
         THEN
            DBMS_OUTPUT.put_line (   RPAD (col_rec (idx).col_name, 30)
                                  || ' = '
                                  || col_value
                                 );
         ELSIF col_value = 'Y'
         THEN
            DBMS_OUTPUT.put_line (   RPAD (col_rec (idx).col_name, 30)
                                  || ' = '
                                  || col_value
                                 );
         END IF;
      END LOOP;

      DBMS_OUTPUT.put_line
                         ('--------------------------------------------------');
   END LOOP;

   DBMS_SQL.close_cursor (c);
END;
/

SET serveroutput off;

目录
相关文章
|
2月前
|
关系型数据库 MySQL 索引
EXPLAIN Output Interpretation
通过分析`EXPLAIN`输出的行列乘积,可评估MySQL连接效率,估算查询所需检查的行数。该乘积还影响`max-join-size`系统变量对多表SELECT语句的执行与中止决策。示例展示了如何逐步优化多表连接,通过调整列类型和大小来减少行乘积,从而提高查询性能。最终,结合索引分析,实现更优的连接效果。
|
2月前
|
JSON 关系型数据库 MySQL
EXPLAIN Join Types
`EXPLAIN` 输出的 `type` 列描述了表连接方式,从最优到最差包括:`system`(单行系统表)、`const`(最多一行,视为常量)、`eq_ref`(最佳连接类型,用于主键或唯一索引)、`ref`(基于索引的部分匹配)、`fulltext`(全文索引)、`ref_or_null`(包含 NULL 值的行)、`index_merge`(索引合并优化)、`unique_subquery` 和 `index_subquery`(索引查找替代子查询)、`range`(索引范围内检索)、`index`(索引扫描)、`ALL`(全表扫描,通常最差)。
|
2月前
|
JSON 关系型数据库 MySQL
EXPLAIN Extra Information
`EXPLAIN` 输出的 `Extra` 列提供了 MySQL 解析查询的附加信息。此列可能的值及其对应的 JSON 属性如下: - **Using filesort / using_filesort**:需额外排序。 - **Using temporary / using_temporary_table**:需创建临时表。 - **Deleting all rows**:删除所有行。 - **Distinct / distinct**:寻找不同值。 - **FirstMatch(tbl_name)**:使用半连接策略。
|
存储 SQL 关系型数据库
Optimizing Queries with EXPLAIN(用explain来优化查询语句)
Optimizing Queries with EXPLAIN(用explain来优化查询语句)
42 0
|
存储 缓存 关系型数据库
explain 之 extra 介绍|学习笔记
快速学习 explain 之 extra 介绍
152 0
|
SQL 存储 关系型数据库