SQL Tuning   «Prev  Next»

Lesson 5The EXPLAIN PLAN statement
ObjectiveUnderstand the basic functions of EXPLAIN PLAN in Oracle AI Database 26ai.

Using EXPLAIN PLAN in Oracle AI Database 26ai

A SQL query describes the result you want, but it does not normally prescribe every operation used to produce that result. Oracle can scan a table, retrieve rows through an index, combine row sources, and sort intermediate results. Before changing a slow query, understand the work its plan proposes. EXPLAIN PLAN provides a practical starting point for that investigation.

In Oracle AI Database 26ai, EXPLAIN PLAN asks the optimizer to generate a plan for a statement and record its operations in a plan table. You then use DBMS_XPLAN.DISPLAY to format those records. The target query is not executed, so the display describes an estimated plan, not a measurement of completed work. This distinction connects to the previous lesson: optimization prepares an execution strategy; execution and fetching perform the work needed to return results.

The statement belongs to Oracle SQL. Submit it through a connected SQL client, such as SQL*Plus, rather than directly at an operating-system prompt. A graphical management tool can make plan inspection convenient, but it is not required. Understanding the command-based workflow helps you recognize what a tool is showing and ask useful questions about its output.

What an estimated plan tells you

A plan describes a tree of operations, also called row sources. It can reveal the proposed access path for a table, the method and order of a join, filtering conditions, and additional work such as sorting or aggregation. Estimates of the number and size of rows help explain why the optimizer considers one strategy preferable to another.

Those estimates do not report elapsed time, physical reads, or rows actually returned by a completed execution. A low estimated cost is not proof that a query is fast. Likewise, the appearance of an index is not proof that a plan is efficient. Use the display to form a specific hypothesis, then obtain runtime evidence when investigating a real performance problem.

The explanation environment matters. A plan generated in a practice schema can differ from the application's plan because the objects, statistics, bind values or types, and optimizer settings differ. Keep the statement and environment representative of the problem you intend to study.

Prepare a practice session

The example uses the optional HR.EMPLOYEES sample table. It must exist in your database, and your account must have permission to query it. Oracle installations do not necessarily include the HR sample schema. If it is unavailable, use a suitable training database or ask the administrator for the intended practice objects. An object-not-found error does not necessarily mean that EXPLAIN PLAN is broken.

Run the steps in the same database session. Modern Oracle supplies the default PLAN_TABLE through a synonym for a system-created global temporary table, with session-private data. You normally do not need to create the table yourself. If a local object named PLAN_TABLE shadows the supplied synonym, or an older custom plan table causes problems, investigate the object and its definition with the administrator before changing it.

Your account needs the privileges required to explain the target statement and to use the selected plan table. A custom table can have different access requirements. Routine practice does not require connecting as SYSDBA. Use the account and database service intended for the exercise so that object resolution and permissions are predictable.

These commands adjust SQL*Plus output width and page length. They are client presentation settings, not SQL statements executed by the database. Another client may provide equivalent display preferences.

SET LINESIZE 160
SET PAGESIZE 100

Step 1: Choose a label for the plan

A statement identifier distinguishes this explanation from other plans stored in the same session. Use M2L5_DEPT50 for this example. Before repeating it, remove only earlier plan records carrying that label:

DELETE FROM plan_table
WHERE statement_id = 'M2L5_DEPT50';

This cleanup changes plan-table records, not employee data. It avoids leaving several demonstrations under the same label and makes the selected result easier to identify. To preserve an earlier explanation, choose another label instead and use it consistently in both the explanation and display commands.

Do not add an unconditional COMMIT merely to view the plan. Your session can read its own changes, and a commit can also commit unrelated work. Similarly, an automatic rollback could undo unrelated work. Manage the transaction according to your practice environment rather than treating either command as a required display step.

Step 2: Explain a complete SELECT statement

This query requests employee identifiers and last names for department 50, ordered by last name. The complete statement includes its selected columns, source table, filtering condition, and ordering requirement:

EXPLAIN PLAN SET STATEMENT_ID = 'M2L5_DEPT50' FOR
SELECT employee_id, last_name
FROM hr.employees
WHERE department_id = 50
ORDER BY last_name;

The SQL following FOR is the target statement. Oracle checks and optimizes it, then inserts records describing proposed operations into PLAN_TABLE. It does not return matching employees at this stage. An explanation-success message means that plan generation succeeded, not that the target query ran successfully or met a performance goal.

Keep the statement complete when copying it into a client. A SELECT list without its FROM clause cannot explain how a table is accessed. Avoid copying client prompts or line numbers into the SQL. These are instructional examples, not commands accompanied by claimed output from a database execution.

The plan depends on available indexes, table and column statistics, and other optimizer inputs. Your result may use a full table scan or an index-based path. Do not add an index or hint simply to make your display resemble someone else's. First understand why the optimizer chose the available strategy for your data.

Step 3: Display the labelled plan

Use Oracle's formatting package to display the records:

SELECT *
FROM TABLE(
  DBMS_XPLAN.DISPLAY('PLAN_TABLE', 'M2L5_DEPT50', 'TYPICAL')
);

The first argument identifies the plan table. The second selects the statement label used above. The third requests the typical display format. The TABLE expression lets SQL query rows returned by the table function. This query reads the explanation records; it does not execute the employee query.

An explicit label makes the example easier to repeat and review than relying on whichever explanation happens to be most recent. Keep the same connection open between generation and display. Another worksheet may use a different session and therefore different session-private records.

DBMS_XPLAN preserves context that a simple query of operation names can omit: indentation, predicate details, and applicable notes. Handwritten hierarchical queries can support specialized analysis, but introduce unnecessary complexity into this basic workflow.

Read the output fields

Field guide to a typical estimated-plan display
FieldMeaning
IdAn operation identifier used to associate an operation with predicate information.
OperationThe action, such as a scan, sort, or join. Indentation shows relationships.
NameThe referenced table, index, or other object, when applicable.
Rows and BytesEstimated output cardinality and data volume, not measured rows from the target query.
Cost and TimeOptimizer estimates. Cost is not seconds; estimated time is not a benchmark.
Predicate InformationAccess and filter conditions associated with operation IDs.
NotesContext such as dynamic statistics or adaptive-plan information, when applicable.
This is a reading guide, not captured output from the example. Operations, estimates, object names, and notes depend on your database.

Start with the table and the condition selecting its rows. Then trace how those rows feed other operations. For this example, ask where DEPARTMENT_ID = 50 is applied and how ordering by LAST_NAME is satisfied. These questions connect the tree to the SQL instead of reducing plan reading to a search for one keyword.

Read predicates alongside operations. An access predicate helps locate rows through an access path or combine row sources; a filter predicate tests rows at an operation. Placement matters when explaining where work occurs. However, a predicate labelled filter is not automatically an error or a reason to force an index.

Understand operations and tree structure

TABLE ACCESS FULL describes a full table scan. It can be appropriate for a small table or a query needing a substantial part of the data. INDEX RANGE SCAN describes access to a range of index entries. When the index does not supply all requested columns, TABLE ACCESS BY INDEX ROWID can retrieve corresponding table rows.

SORT ORDER BY describes sorting to satisfy an ordering requirement. The query contains ORDER BY, but that does not guarantee a separate sort: an access path can sometimes provide the required order. Conversely, an index on a filtering column does not automatically satisfy ordering by another column.

For queries involving multiple tables, operations such as NESTED LOOPS and HASH JOIN describe different ways to combine row sources. The single-table example does not require a join. Recognize these names for later lessons without expecting every plan to contain them or assuming one join method is universally best.

Indentation expresses parent-child relationships. A parent consumes rows produced by its children, but the display is not a stopwatch timeline. Some operations request rows repeatedly, others pass rows along as they become available, and blocking operations may need substantial input before returning output. Parallel execution can further complicate timing relationships.

Do not interpret operation IDs as an execution counter or apply a universal bottom-to-top reading rule. Identify each operation's inputs and output. In a nested loops join, for example, the inner input can be visited repeatedly for rows from the outer input. The tree describes dependencies more usefully than a single linear ordering.

Avoid adding all displayed costs together to produce a supposed query duration. Costs reflect the optimizer's model and can represent work across an operation's subtree. Use estimates to understand choices within a relevant comparison, then measurements to evaluate application performance.

Move from estimates to runtime evidence

EXPLAIN PLAN helps you learn a statement's likely structure or examine a proposed rewrite before executing it. For an application query that is already slow, inspect the intended cached cursor as well. A separately generated explanation may not match the plan used by that execution.

Select the display function for the evidence you need
FunctionPurposeLimit
DBMS_XPLAN.DISPLAYFormats plan-table records, commonly produced by EXPLAIN PLAN.Does not measure target-query execution.
DBMS_XPLAN.DISPLAY_CURSORDisplays a loaded cursor's plan and available collected statistics.Requires the correct cursor, view access, and collected statistics for runtime analysis.

Identify the intended SQL_ID and child cursor before using DISPLAY_CURSOR. Different child cursors can exist for a statement. Displaying an unrelated or merely recent cursor can lead to the wrong diagnosis. Cached-cursor inspection does not require retrieving a historical plan from AWR; these are different evidence sources.

The ALLSTATS LAST display option requests available statistics for the last execution of the selected cursor. It does not retrospectively collect measurements. Statistics must have been collected during execution, for example with a deliberately scoped gather_plan_statistics hint. Use the controlled approach introduced in the SQL tuning tool set lesson rather than enabling broad diagnostics merely to fill display columns.

For a SELECT, consider how many results the application fetched. Measuring a query that fetches only the first screen of rows can answer a different question from measuring complete result consumption. Match the measurement to the user's performance goal and record that context with the plan.

Troubleshoot the workflow

If generation fails, check the target SQL, schema qualification, object availability, and privileges. If generation succeeds but the display is empty or unexpected, check the session, plan-table name, and statement label. A typographical difference in the label can be enough to display no matching plan.

If the plan differs from a textbook example, compare the data and environment before assuming a fault. Statistics, indexes, and settings can legitimately produce different choices. If an estimate seems implausible, record the questionable operation and predicate, then compare estimates with collected runtime evidence in a controlled test.

If output wraps awkwardly, increase the client display width or use its text output view. Formatting problems do not mean that the optimizer generated an invalid plan. Preserve the complete output, including predicates and notes, when sharing results for review.

Use the plan to guide a measurable change

Begin with a specific question: which operation appears to do unnecessary work, and why? Preserve a baseline, change one relevant factor, verify that the query still returns the required result, and compare representative measurements. Neither fewer plan lines nor a lower estimated cost alone proves improvement.

You should now be able to explain a complete statement, display its labelled plan, identify operations and predicates, and distinguish estimates from execution evidence. The next lesson examines optimizer modes and how the optimization goal relates to response time and throughput.

Oracle 26ai references

SEMrush Software 5 SEMrush Banner 5