PL/SQL Packages and Types Reference 10g Release 1 (10.1) Part Number B10802-01 |
|
|
View PDF |
The DBMS_XPLAN
package provides an easy way to display the output of the EXPLAIN PLAN
command in several, predefined formats. You can also use the DBMS_XPLAN package to display the plan of a statement stored in the Automatic Workload Repository (AWR).It further provides a way to display the SQL execution plan and SQL execution runtime statistics for cached SQL cursors based on the information stored in the V$SQL_PLAN
and V$SQL_PLAN_STATISTICS_ALL
fixed views.
For more information on the EXPLAIN
PLAN
command and the AWR, see Oracle Database Performance Tuning Guide. For more information on the V$SQL_PLAN
and V$SQL_PLAN_STATISTICS
fixed views, see Oracle Database Reference.
This chapter contains the following topics:
The DBMS_XPLAN
package supplies three table functions:
DISPLAY
, to format and display the contents of a plan tableDISPLAY_CURSOR
, to format and display the contents of the execution plan of any loaded cursor.This package runs with the privileges of the calling user, not the package owner (SYS). The table function DISPLAY_CURSOR requires to have select privileges on the following fixed views: V$SQL_PLAN, V$SESSION and V$SQL_PLAN_STATISTICS_ALL.
Using the DISPLAY_AWR function requires to have SELECT privileges on DBA_HIST_SQL_PLAN, DBA_HIST_SQLTEXT, and V$DATABASE.
All these privileges are automatically granted as part of the SELECT_CATALOG role.
Execute an explain plan command on a SELECT
statement:
EXPLAIN PLAN FOR SELECT * FROM emp e, dept d WHERE e.deptno = d.deptno AND e.ename='benoit';
Display the plan using the DBMS_XPLAN.DISPLAY
table function
SET LINESIZE 130 SET PAGESIZE 0 SELECT * FROM table(DBMS_XPLAN.DISPLAY);
This query produces the following output:
Plan hash value: 3693697075 --------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 57 | 6 (34)| 00:00:01 | |* 1 | HASH JOIN | | 1 | 57 | 6 (34)| 00:00:01 | |* 2 | TABLE ACCESS FULL| EMP | 1 | 37 | 3 (34)| 00:00:01 | | 3 | TABLE ACCESS FULL| DEPT | 4 | 80 | 3 (34)| 00:00:01 | --------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("E"."DEPTNO"="D"."DEPTNO") 2 - filter("E"."ENAME"='benoit') 15 rows selected.
By default, the table function DISPLAY_CURSOR
formats the execution plan for the last SQL statement executed by the session. For example:
SELECT ename FROM emp e, dept d WHERE e.deptno = d.deptno AND e.empno=7369; ENAME ---------- SMITH
To display the execution plan of the last executed statement for that session:
SET PAGESIZE 0 SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR);
This query produces the following output:
Plan hash value: 3693697075, SQL hash value: 2096952573, child number: 0 ------------------------------------------------------------------ SELECT ename FROM emp e, dept d WHERE e.deptno = d.deptno AND e.empno=7369 --------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | | | |* 1 | HASH JOIN | | 1 | 16 | 6 (34)| 00:00:01 | |* 2 | TABLE ACCESS FULL| EMP | 1 | 13 | 3 (34)| 00:00:01 | | 3 | TABLE ACCESS FULL| DEPT | 4 | 12 | 3 (34)| 00:00:01 | --------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("E"."DEPTNO"="D"."DEPTNO") 2 - filter("E"."EMPNO"=7369) 21 rows selected.
You can also use the table function DISPLAY_CURSOR
to display the execution plan for any loaded cursor stored in the cursor cache. In that case, you must supply a reference to the child cursor to the table function. This includes the SQL ID of the statement and optionally the child number.
Run a query with a distinctive comment:
SELECT /* TOTO */ ename, dname FROM dept d join emp e USING (deptno);
Get sql_id
and child_number
for the preceding statement:
SELECT sql_id, child_number FROM v$sql WHERE sql_text LIKE '%TOTO%'; SQL_ID CHILD_NUMBER ---------- ----------------------------- gwp663cqh5qbf 0
Display the execution plan for the cursor:
SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR(('gwp663cqh5qbf',0)); Plan hash value: 3693697075, SQL ID: gwp663cqh5qbf, child number: 0 -------------------------------------------------------- SELECT /* TOTO */ ename, dname FROM dept d JOIN emp e USING (deptno); ---------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 7 (100)| | | 1 | SORT GROUP BY | | 4 | 64 | 7 (43)| 00:00:01 | |* 2 | HASH JOIN | | 14 | 224 | 6 (34)| 00:00:01 | | 3 | TABLE ACCESS FULL| DEPT | 4 | 44 | 3 (34)| 00:00:01 | | 4 | TABLE ACCESS FULL| EMP | 14 | 70 | 3 (34)| 00:00:01 | ---------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("E"."DEPTNO"="D"."DEPTNO")
Instead of issuing two queries, one to the get the sql_id and child_number pair and one to display the plan, you can combine these in a single query:
Display the execution plan of all cursors matching the string 'TOTO':
SELECT t.* FROM v$sql s, table(DBMS_XPLAN.DISPLAY_CURSOR(s.sql_id, s.child_number)) t WHERE sql_text LIKE '%TOTO%';
By default, only relevant information is reported by the display and display_cursor table functions. In Displaying a Plan Table Using DBMS_XPLAN.DISPLAY, the query does not execute in parallel. Hence, information related to the parallelization of the plan is not reported. As shown in the following example, parallel information is reported only if the query executes in parallel.
ALTER TABLE emp PARALLEL; EXPLAIN PLAN for SELECT * FROM emp e, dept d WHERE e.deptno = d.deptno AND e.ename ='hermann' ORDER BY e.empno;
Display the plan using the DBMS_XPLAN.DISPLAY
table function
SET LINESIZE 130 SET PAGESIZE 0 SELECT * FROM table(DBMS_XPLAN.DISPLAY); Plan hash value: 3693697345
------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |INOUT |PQ Distrib | ------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 117 | 6 (50) | 00:00:01 | | | | | 1 | PX COORDINATOR | | | | | | | | | | 2 | PX SEND QC (ORDER) |:TQ10003 | 1 | 117 | 6 (50) | 00:00:01 | Q1,03 | P->S | QC (ORDER)| | 3 | SORT ORDER BY | | 1 | 117 | 6 (50) | 00:00:01 | Q1,03 | PCWP | | | 4 | PX RECEIVE | | 1 | 117 | 5 (40) | 00:00:01 | Q1,03 | PCWP | | | 5 | PX SEND RANGE |:TQ10002 | 1 | 117 | 5 (40) | 00:00:01 | Q1,02 | P->P | RANGE | |* 6 | HASH JOIN | | 1 | 117 | 5 (40) | 00:00:01 | Q1,02 | PCWP | | | 7 | PX RECEIVE | | 1 | 87 | 2 (50) | 00:00:01 | Q1,02 | PCWP | | | 8 | PX SEND HASH |:TQ10001 | 1 | 87 | 2 (50) | 00:00:01 | Q1,01 | P->P | HASH | | 9 | PX BLOCK ITERATOR | | 1 | 87 | 2 (50) | 00:00:01 | Q1,01 | PCWC | | |* 10| TABLE ACCESS FULL | EMP | 1 | 87 | 2 (50) | 00:00:01 | Q1,01 | PCWP | | | 11 | BUFFER SORT | | | | | | Q1,02 | PCWC | | | 12 | PX RECEIVE | | 4 | 120 | 3 (34) | 00:00:01 | Q1,02 | PCWP | | | 13 | PX SEND HASH |:TQ10000 | 4 | 120 | 3 (34) | 00:00:01 | | S->P | HASH | | 14 | TABLE ACCESS FULL | DEPT | 4 | 120 | 3 (34) | 00:00:01 | | | | ------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 6 - access("E"."DEPTNO"="D"."DEPTNO") 10 - filter("E"."ENAME"='hermann') ---------------------------------------------------
When the query is parallel, information related to parallelism is reported: table queue number (TQ
column), table queue type (INOUT
) and table queue distribution method (PQ Distrib
).
By default, if several plans in the plan table match the statement_id
parameter passed to the display table function (default value is NULL
), only the plan corresponding to the last EXPLAIN
PLAN
command is displayed. Hence, there is no need to purge the plan table after each EXPLAIN
PLAN
. However, you should purge the plan table regularly (for example, by using the TRUNCATE
TABLE
command) to ensure good performance in the execution of the DISPLAY
table function.
For ease of use, you can define a view on top of the display table function and then use that view to display the output of the EXPLAIN
PLAN
command:
# define plan view CREATE VIEW PLAN AS SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); # display the output of the last explain plan command SELECT * FROM PLAN;
Subprogram | Description |
---|---|
Displays the contents of an execution plan stored in the AWR | |
Displays the contents of the plan table | |
Displays the execution plan of any cursor in the cursor cache |
This table function displays the contents of an execution plan stored in the AWR.
DBMS_XPLAN.DISPLAY_AWR( sql_id IN VARCHAR2, plan_hash_value IN NUMBER DEFAULT NULL, db_id IN NUMBER DEFAULT NULL, format IN VARCHAR2 DEFAULT TYPICAL);
To use the DISPLAY_AWR
functionality, the calling user must have SELECT
privilege on DBA_HIST_SQL_PLAN
. DBA_HIST_SQLTEXT
, and V$DATABASE
, otherwise it will show an appropriate error message.
To display the execution plan of all children associated to the SQL ID 'atfwcg8anrykp
':
SELECT * FROM table(DBMS_XPLAN.DISPLAY_AWR('atfwcg8anrykp'));
To display the execution plan of all stored SQL statements containing the string 'TOTO
':
SELECT tf.* FROM DBA_HIST_SQLTEXT ht, table (DBMS_XPLAN.DISPLAY_AWR(ht.sql_id,null, null, 'ALL' )) tf WHERE ht.sql_text like '%TOTO%';
This table function displays the contents of the plan table.
DBMS_XPLAN.DISPLAY( table_name IN VARCHAR2 DEFAULT 'PLAN_TABLE', statement_id IN VARCHAR2 DEFAULT NULL, format IN VARCHAR2 DEFAULT 'TYPICAL');
To display the result of the last EXPLAIN
PLAN
command stored in the plan table:
SELECT * FROM table(DBMS_XPLAN.DISPLAY);
To display from other than the default plan table, "my_plan_table
":
SELECT * FROM table(DBMS_XPLAN.DISPLAY('my_plan_table'));
To display the minimum plan information:
SELECT * FROM table(DBMS_XPLAN.DISPLAY('plan_table', null, 'basic'));
To display the plan for a statement identified by 'foo
', such as statement_id='foo'
:
SELECT * FROM table(DBMS_XPLAN.DISPLAY('plan_table', 'foo'));
DBMS_XPLAN.DISPLAY_CURSOR( sql_id IN VARCHAR2 DEFAULT NULL, child_number IN NUMBER DEFAULT NULL, format IN VARCHAR2 DEFAULT 'TYPICAL');
To use the DISPLAY_CURSOR
functionality, the calling user must have SELECT
privilege on the fixed views V$SQL_PLAN_STATISTICS_ALL
, V$SQL
and V$SQL_PLAN
, otherwise it will show an appropriate error message.
To display the execution plan of the last SQL
statement executed by the current session:
SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR);
To display the execution plan of all children associated to the SQL ID 'atfwcg8anrykp':
SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR('atfwcg8anrykp'));
To display runtime statistics for the cursor included in the preceding statement:
SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR('atfwcg8anrykp', null, 'RUNSTATS_ LAST');