6 Generating and Displaying Execution Plans

6.1 Introduction to Execution Plans

The combination of the steps that Oracle Database uses to execute a statement is an execution plan. Each step either retrieves rows of data physically from the database or prepares them for the user issuing the statement. An execution plan includes an access path for each table that the statement accesses and an ordering of the tables (the join order) with the appropriate join method.

6.2.1 About the Plan Explanation

A statement execution plan is the sequence of operations that the database performs to run the statement. The row source tree is the core of the execution plan (see "SQL Row Source Generation"). The tree shows the following information:

An ordering of the tables referenced by the statement

An access method for each table mentioned in the statement

A join method for tables affected by join operations in the statement

Data operations like filter, sort, or aggregation

In addition to the row source tree, the plan table contains information about the following:

Optimization, such as the cost and cardinality of each operation

Partitioning, such as the set of accessed partitions

Parallel execution, such as the distribution method of join inputs

The EXPLAINPLAN results enables you to determine whether the optimizer selects a particular execution plan, such as a nested loops join. The results also help you to understand the optimizer decisions, such as why the optimizer chose a nested loops join instead of a hash join, and enables you to understand the performance of a query.

6.2.2 Why Execution Plans Change

Execution plans can and do change as the underlying optimizer inputs change. EXPLAINPLAN output shows how the database would run the SQL statement when the statement was explained. This plan can differ from the actual execution plan a SQL statement uses because of differences in the execution environment and explain plan environment.

Note:

To avoid possible SQL performance regression that may result from execution plan changes, consider using SQL plan management.

6.2.2.1 Different Schemas

The user explaining the statement is different from the user running the statement. Two users might be pointing to different objects in the same database, resulting in different execution plans.

Schema changes (usually changes in indexes) between the two operations.

6.2.2.2 Different Costs

Even if the schemas are the same, the optimizer can choose different execution plans when the costs are different. Some factors that affect the costs include the following:

Data volume and statistics

Bind variable types and values

Initialization parameters set globally or at session level

6.2.3 Minimizing Throw-Away

Examining an explain plan enables you to look for throw-away in cases such as the following:

Full scans

Unselective range scans

Late predicate filters

Wrong join order

Late filter operations

In the plan shown in Example 6-1, the last step is a very unselective range scan that is executed 76563 times, accesses 11432983 rows, throws away 99% of them, and retains 76563 rows. Why access 11432983 rows to realize that only 76563 rows are needed?

6.2.4 Looking Beyond Execution Plans

The execution plan operation alone cannot differentiate between well-tuned statements and those that perform poorly. For example, an EXPLAINPLAN output that shows that a statement uses an index does not necessarily mean that the statement runs efficiently. Sometimes indexes are extremely inefficient. In this case, you should examine the following:

The columns of the index being used

Their selectivity (fraction of table being accessed)

It is best to use EXPLAINPLAN to determine an access plan, and then later prove that it is the optimal plan through testing. When evaluating a plan, examine the statement's actual resource consumption.

6.2.4.1 Using V$SQL_PLAN Views

In addition to running the EXPLAINPLAN command and displaying the plan, you can use the V$SQL_PLAN views to display the execution plan of a SQL statement:

After the statement has executed, you can display the plan by querying the V$SQL_PLAN view. V$SQL_PLAN contains the execution plan for every statement stored in the shared SQL area. Its definition is similar to the PLAN_TABLE. See "PLAN_TABLE Columns".

The advantage of V$SQL_PLAN over EXPLAINPLAN is that you do not need to know the compilation environment that was used to execute a particular statement. For EXPLAINPLAN, you would need to set up an identical environment to get the same plan when executing the statement.

The V$SQL_PLAN_STATISTICS view provides the actual execution statistics for every operation in the plan, such as the number of output rows and elapsed time. All statistics, except the number of output rows, are cumulative. For example, the statistics for a join operation also includes the statistics for its two inputs. The statistics in V$SQL_PLAN_STATISTICS are available for cursors that have been compiled with the STATISTICS_LEVEL initialization parameter set to ALL.

The V$SQL_PLAN_STATISTICS_ALL view enables side by side comparisons of the estimates that the optimizer provides for the number of rows and elapsed time. This view combines both V$SQL_PLAN and V$SQL_PLAN_STATISTICS information for every cursor.

6.2.5 EXPLAIN PLAN Restrictions

Oracle Database does not support EXPLAINPLAN for statements performing implicit type conversion of date bind variables. With bind variables in general, the EXPLAINPLAN output might not represent the real execution plan.

From the text of a SQL statement, TKPROF cannot determine the types of the bind variables. It assumes that the type is CHARACTER, and gives an error message otherwise. You can avoid this limitation by putting appropriate type conversions in the SQL statement.

6.2.6 The PLAN_TABLE Output Table

The PLAN_TABLE is automatically created as a public synonym to a global temporary table. This temporary table holds the output of EXPLAINPLAN statements for all users. PLAN_TABLE is the default sample output table into which the EXPLAINPLAN statement inserts rows describing execution plans. See "PLAN_TABLE Columns" for a description of the columns in the table.

While a PLAN_TABLE table is automatically set up for each user, you can use the SQL script catplan.sql to manually create the global temporary table and the PLAN_TABLE synonym. The name and location of this script depends on your operating system. On UNIX and Linux, the script is located in the $ORACLE_HOME/rdbms/admin directory.

For example, start a SQL*Plus session, connect with SYSDBA privileges, and run the script as follows:

@$ORACLE_HOME/rdbms/admin/catplan.sql

Oracle recommends that you drop and rebuild your local PLAN_TABLE table after upgrading the version of the database because the columns might change. This can cause scripts to fail or cause TKPROF to fail, if you are specifying the table.

If you do not want to use the name PLAN_TABLE, create a new synonym after running the catplan.sql script. For example:

CREATE OR REPLACE PUBLIC SYNONYM my_plan_table for plan_table$

6.3 Generating Execution Plans

The EXPLAIN PLAN statement enables you to examine the execution plan that the optimizer chose for a SQL statement. When the statement is issued, the optimizer chooses an execution plan and then inserts data describing the plan into a database table. Issue the EXPLAIN PLAN statement and then query the output table.

After issuing the EXPLAIN PLAN statement, use a script or package provided by Oracle Database to display the most recent plan table output. See "Displaying PLAN_TABLE Output".

The execution order in EXPLAIN PLAN output begins with the line that is the furthest indented to the right. The next step is the parent of that line. If two lines are indented equally, then the top line is normally executed first.

Notes:

The EXPLAINPLAN output tables in this chapter were displayed with the utlxpls.sql script.

The steps in the EXPLAINPLAN output in this chapter may be different on your system. The optimizer may choose different execution plans, depending on database configurations.

To explain a SQL statement, use the EXPLAINPLANFOR clause immediately before the statement. For example: