Vous êtes sur la page 1sur 8

Copyright (c) 2018, Oracle. All rights reserved. Oracle Confidential.

* How to Obtain a Formatted Explain Plan - Recommended Methods (Doc ID 235530.1)

In this Document

Goal
Solution
Obtaining a Formatted Explain Plan
Manual Methods of Displaying the Plan
SQL_ID and HASH_VALUE of the SQL
Version 10.2 and higher
Last Executed SQL
SQL_ID and child number of the SQL are known
gather_plan_statistics hint
Plan from Memory
From Automatic Workload Repository (AWR)
From SQL Tuning Set (STS)
From SQL Plan Baseline
Identifying the SQL
sql_id:
cursor_child_no:
Legacy Information
Version 9.2 and higher
Dbms_xplan
v$sql_plan
Versions 8.1.7 and 9.0.1
Serial Plans
Parallel Plans
Autotrace
Creating Plan Table
Populating the Plan Table
References

APPLIES TO:

Oracle Database - Enterprise Edition - Version 8.1.5.0 and later


Oracle Database - Standard Edition - Version 7.0.16.0 and later
Oracle Database - Personal Edition - Version 7.1.4.0 and later
Oracle Database Cloud Schema Service - Version N/A and later
Oracle Database Exadata Cloud Machine - Version N/A and later
Information in this document applies to any platform.

GOAL

This article outlines how to use Oracle supplied utilities to obtain a formatted explain plan.
SOLUTION

Obtaining a Formatted Explain Plan

Support currently recommends the use of the SQLTXPLAIN(SQLT) utility to collect explain plan information. Manual methods
are also included in this article for the cases where the use of SQLT is not possible.

SQLTXPLAIN(SQLT) display the plan along with a comprehensive set of information you can use to diagnose and improve
query performance. It inputs one SQL statement and outputs a set of diagnostics files including execution plans, Cost-based
Optimizer CBO statistics, schema objects metadata, performance statistics, configuration parameters, and similar elements
that influence the performance of the SQL being analyzed.

Unless you plan to execute the SQL, you will need to know the SQL_ID or HASH_VALUE of the statement from an AWR or ASH
report or you can select it from the database using the V$SQL view. See:

Document 1627387.1 How to Determine the SQL_ID for a SQL Statement

SQLT also supplies additional information that can be helpful in understanding why a particular execution plan has been
chosen.
The following note explains how to install and use SQLT

Document 215187.1 SQLT Diagnostic Tool


Document 1614107.1 SQLT Usage Instructions

Instructions are also provided in the SQLT download file.

There are 4 main ways to use SQLT:

1. XPLAIN - Generates Explain Plan, SQL is not executed


2. XTRACT- Generates Explain Plan for SQL that is already in memory or has been captured by AWR
3. XECUTE -SQL is executed, then Execution Plan is obtained
4. XTRXEC -This method combines the features of XTRACT and XECUTE.

Any of these methods are suitable for producing a formatted explain plan, but XTRXEC covers all options and is recommended.

Remember that in order to use diagnostic information from any part of the Automatic Workload Repository the Diagnostic Pack
License is required. See:

Document 1490798.1 AWR Reporting - Licensing Requirements Clarification

You can also get the plan from the SQL Tuning Health-Check Script (SQLHC) which checks the environment in which a single
SQL Statement runs, checking Cost-based Optimizer (CBO) statistics, schema object metadata, configuration parameters and
other elements that may influence the performance of the one SQL being analyzed. SQLHC collects a subset of the data that
SQLT collects.

Document 1366133.1 SQL Tuning Health-Check Script (SQLHC)

Manual Methods of Displaying the Plan

The method required to obtain a formatted explain plan differs depending on which version of Oracle is being used. The
methods of obtaining the real execution plan in 10.2, that do not require use of the Explain Plan command or the plan table,
are more reliable.
Note: There are limitations with explain plan when the SQL uses implicit type conversions or bind variables. As stated in
the Performance Tuning Guide and Reference:

"Oracle does not support EXPLAIN PLAN for statements performing implicit type conversion of date bind variables. With
bind variables in general, the EXPLAIN PLAN output might not represent the real execution plan."
SQL_ID and HASH_VALUE of the SQL

The SQL_ID and HASH_VALUE of the statement are two values that uniquely identify a SQL statement. They can be obtained
from a number of places, including AWR and ASH reports or you can select them from the database using the V$SQL view.
See:

Document 1627387.1 How to Determine the SQL_ID for a SQL Statement

Version 10.2 and higher

Last Executed SQL

In 10.2 and above, you can pull execution plans from the library cache if the SQL has already been executed (in addition to
the standard explain plan option from earlier releases). To get the plan of the last executed SQL issue the following:

set linesize 150


set pagesize 2000
select * from table(dbms_xplan.display_cursor(null,null, 'ALL'));

SQL_ID and child number of the SQL are known

A SQL_ID can have multiple children with different characteristics. You can identify the child number by selecting from V$SQL
as follows:

SELECT sql_id, hash_value, child_number, SUBSTR(sql_text,1,40) Text


FROM v$sql
WHERE sql_text LIKE '%&Some_Identifiable_String%'
/

The first child for a cursor will have a CHILD_NUMBER of zero.


Once you have this information, you can use dbms_xplan.display_cursor as follows:

set linesize 150


set pagesize 2000
select * from TABLE(dbms_xplan.display_cursor('&SQL_ID', &CHILD));

gather_plan_statistics hint

The gather_plan_statistics hint with some additional options may also provide run time statistics:e.g:

select /*+ gather_plan_statistics */ col1, col2 etc.....

set linesize 150


set pagesize 2000
select * from TABLE(dbms_xplan.display_cursor('&SQL_ID', &CHILD,'ALL IOSTATS LAST'))

Make sure the syntax is correct in the hint /*+ gather_plan_statistics */. Do not use explain plan
for:
EXPLAIN PLAN FOR
SELECT /* +GATHER_PLAN_STATISTICS */ * FROM tab1
WHERE...

Otherwise following error will occur:


 

- 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

Correct syntax is following:


 

SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM tab1


WHERE
..

select * from table(dbms_xplan.display_cursor(null,null,'advanced ALLSTATS LAST'));

Plan from Memory

For SQL ID :
select * from table(dbms_xplan.display_cursor('&sql_id'));
select * from table(dbms_xplan.display_cursor('&sql_id', NULL, 'ALL'));

For SQL ID, Child Cursor :


select * from table(dbms_xplan.display_cursor('&sql_id', &child_number, 'ALL'));

For SQL Text :


select t.*
from v$sql s, table(dbms_xplan.display_cursor(s.sql_id, s.child_number, 'ALL')) t
where s.sql_text like '%&querystring%';

From Automatic Workload Repository (AWR)

With the appropriate licenses, you can extract the plan for a particular SQL statement for a specific time period from the
Automatic Workload Repository (AWR). In order to use diagnostic information from any part of the Automatic Workload
Repository the Diagnostic Pack License is required. See:

Document 1490798.1 AWR Reporting - Licensing Requirements Clarification

AWR SQL report is an easy means of obtaining an execution plan from a certain period of time. Use the following command to
initiate the report:

$ORACLE_HOME/rdbms/admin/awrsqrpt.sql

You can also select information directly using the SQL_ID as follows:

For SQL ID :
select * from table(dbms_xplan.display_awr('&sql_id')) ;
select * from table(dbms_xplan.display_awr('&sql_id', NULL, NULL, 'ALL')) ;

For SQL ID, Plan Hash Value in the current database :


select * from table(dbms_xplan.display_awr('&sql_id', '&plan_hash_value', NULL, 'ALL')) ;
For SQL ID, Plan Hash Value in a different database ID :
select * from table(dbms_xplan.display_awr('&sql_id', '&plan_hash_value', &dbid, 'ALL')) ;

For SQL ID that was executed during a certain period :


select t.*
from (select distinct sql_id, plan_hash_value, dbid
from dba_hist_sqlstat
where sql_id = '&sql_id'
and snap_id between &begin_snap and &end_snap) s,
table(dbms_xplan.display_awr(s.sql_id, s.plan_hash_value, s.dbid, 'ALL')) t;

For SQL Text :


select t.*
from (select distinct r.sql_id sql_id, r.plan_hash_value plan_hash_value, r.dbid dbid
from dba_hist_sqltext q, dba_hist_sqlstat r
where q.sql_id = r.sql_id
and q.sql_text like '%&querystring%') s,
table(dbms_xplan.display_awr(s.sql_id, s.plan_hash_value, s.dbid, 'ALL')) t;

From SQL Tuning Set (STS)

Note : STS owner is the current user by default.

For SQL ID in a STS :


select * from table (dbms_xplan.display_sqlset( '&sts_name','&sql_id'));

For All Statements in a STS :


select t.*
from dba_sqlset_statements s, table(dbms_xplan.display_sqlset(s.sqlset_name, s.sql_id,
s.plan_hash_value, 'ALL', s.sqlset_owner)) t
where s.sqlset_name = '&sts_name';

For SQL ID, Plan Hash Value in a STS :


select * from table (dbms_xplan.display_sqlset( '&sts_name','&sql_id', '&plan_hash_value',
'ALL'));

For SQL ID, Plan Hash Value, STS Owner :


select * from table (dbms_xplan.display_sqlset( '&sts_name','&sql_id', '&plan_hash_value', 'ALL',
'&sts_owner'));

For SQL Text in a STS :


select t.*
from dba_sqlset_statements s, table(dbms_xplan.display_sqlset(s.sqlset_name, s.sql_id,
s.plan_hash_value, 'ALL', s.sqlset_owner)) t
where s.sqlset_name = '&sts_name'
and s.sql_text like '%&querystring%';

From SQL Plan Baseline

For SQL Handle :


select * from table(dbms_xplan.display_sql_plan_baseline('&sql_handle'));

For SQL Handle, Plan Name :


select * from table(dbms_xplan.display_sql_plan_baseline('&sql_handle', '&plan_name', 'ALL'));

For SQL Text :


select t.*
from (select distinct sql_handle, plan_name
from dba_sql_plan_baselines
where sql_text like '%&querystring%') s,
table(dbms_xplan.display_sql_plan_baseline(s.sql_handle, s.plan_name, 'ALL')) t;
Identifying the SQL

sql_id:

The SQL_ID specifies the sql_id value for a specific SQL statement, and can be found in:

V$SQL.SQL_ID,
V$SESSION.SQL_ID,
V$SESSION.PREV_SQL_ID,
V$SQL.SQL_ID,
V$SESSION.SQL_ID,
V$SESSION.PREV_SQL_ID.

If no sql_id is specified, the last executed statement of the current session is shown.

cursor_child_no:

The child cursor number specifies the child number for a specific sql cursor, and can be found in:

V$SQL.CHILD_NUMBER
V$SESSION.SQL_CHILD_NUMBER
V$SESSION.PREV_CHILD_NUMBER.

If not specified, all child cursors for the specified sql_id are displayed.

To workaround unpublished Bug:6501604 DBMS_XPLAN.DISPLAY_CURSOR NOT DISPLAYING ALL CHILD AS EXPECTED see:
Document 465398.1 to display all child cursors for the specified sql_id

Note: To use the DISPLAY_CURSOR functionality, the calling user must have
SELECT privilege on V$SQL_PLAN_STATISTICS_ALL, V$SQL, and V$SQL_PLAN, otherwise an appropriate error message
will be displayed.

Additionally to see the row counts etc for a parallel query see:

Note 1114405.1 How to force that a Parallel Query runs in serial with the Parallel Execution Plan

Legacy Information

Version 9.2 and higher

Dbms_xplan

With Oracle 9.2, Oracle supplies a utility called dbms_xplan. It is created by dbmsutil.sql which is called by catproc.sql. As such
it should already be installed on most 9.2 databases.

To generate a formatted explain plan of the query that has just been 'explained':

SQL> set lines 130


SQL> set head off
SQL> spool
SQL> alter session set cursor_sharing=EXACT;
SQL> select plan_table_output from table(dbms_xplan.display('PLAN_TABLE',null,'ALL'));
SQL> spool off
v$sql_plan

If the SQL has been executed, and you know the hash value of the SQL, you can pull the plan from v$sql_plan as described
in:

Note 260942.1 Display Execution plans from Statements in V$SQL_PLAN

Versions 8.1.7 and 9.0.1

From version 8.1.5, Oracle has supplied 2 scripts to extract formatted explain plans from plan_tables. One is for serial plans
and the other is for parallel plans. Scripts can be found under $ORACLE_HOME/rdbms/admin.
Examples of their usage are below.

Serial Plans

To obtain a formatted execution plan for serial plans:

SQL> set lines 130


SQL> set head off
SQL> spool
SQL> @@?/rdbms/admin/utlxpls
SQL> spool off

Parallel Plans

To obtain a formatted execution plan for parallel plans:

SQL> set lines 130


SQL> set head off
SQL> spool
SQL> @@?/rdbms/admin/utlxplp
SQL> spool off

Autotrace

Autotrace can also be used. It shows more information about distributed queries but in earlier versions, the output is often
badly formatted. If using autotrace, there is no need to 'explain' the query

SQL> set lines 130


SQL> set long 2000
SQL> set head off
SQL> spool >>spool file <<
SQL> set autotrace trace explain
SQL> @@ >> your query <<
SQL> spool off

Creating Plan Table

If required, the initial steps to create a plan table and make the optimizer populate the plan table with the execution plan are
common to all supported versions of Oracle.
1. Use the utlxplan.sql script to create the plan table as instructed below.

SQL> @@?/rdbms/admin/utlxplan

2. On 10g and above there is a new script - catplan.sql - to create the plan table that
creates a public plan table as a global temporary table accessible from any schema

SQL> @@?/rdbms/admin/catplan

Note that the plan table format can change between versions so ensure that it is created using the utlxplan script from the
current version

Populating the Plan Table

SQL> explain plan for >> your query goes here <<
Explained.

REFERENCES

NOTE:130466.1 - How to Obtain the Most Recent Execution Plan in a Simple Nested Form
NOTE:215187.1 - All About the SQLT Diagnostic Tool
NOTE:465398.1 - How to Display All Loaded Execution Plan for a specific sql_id

NOTE:104824.1 - Enhanced Explain Plan Script


NOTE:260942.1 - Display Execution plans from Statement's in V$SQL_PLAN

NOTE:39294.1 - SCRIPT - Formatted Select of PLAN_TABLE for EXPLAIN PLAN command

NOTE:1114405.1 - How to Force a Parallel Query to Run in Serial with the Parallel Execution Plan
Didn't find what you are looking for?

Vous aimerez peut-être aussi