Академический Документы
Профессиональный Документы
Культура Документы
Supplement
Selecting the link title opens the resource in a new browser window.
Learning Aid
Use the learning aid Style considerations for more information on the style
considerations for Oracle 11g Database used in this course.
The execution plan of a SQL statement is composed of small building blocks called row
sources for serial execution plans. The combination of row sources for a statement is also
called the execution plan. By using parent-child relationships, the execution plan can be
displayed in a tree-like structure (text or graphical).
The EXPLAIN PLAN statement gathers execution plans chosen by the Oracle optimizer
for the SELECT, UPDATE, INSERT, and DELETE statements. The steps of the execution
plan are not performed in the order in which they are numbered. There is a parent-child
relationship between steps.
The row source tree is the core of the execution plan. It shows the following information:
a join method for tables affected by join operations in the statement, and
Plan and row source operations are dumped in trace files generated by DBMS_MONITOR.
In the SQL Management Base or SMB, which is a part of the data dictionary that resides in the
SYSAUX tablespace. It stores statement log, plan histories, and SQL plan baselines, as profiles.
The event 10053 trace file, which is used to dump Cost-Based Optimizer, or CBO computations,
may include a plan.
Starting with Oracle Database 10g Release 2, when you dump process state (or errorstack from a
process), execution plans are included in the trace file that is generated.
Question
Which method of retrieving execution plans from the database enables you to
review the execution plan that the optimizer might use to execute a SQL
statement?
Options:
1.
AWR
2.
3.
SMB
4.
V$SQL_PLAN_MONITOR
Answer
Option 1: Incorrect. The Automatic Workload Repository, or AWR, infrastructure
and statspack reports store plans from top SQLs. Plans are recorded into
DBA_HIST_SQL_PLAN and STATS$SQL_PLAN.
Option 2: Correct. The EXPLAIN PLAN command enables you to view the
execution plan that the optimizer might use to execute a SQL statement. This
command is very useful because it outlines the plan that the optimizer may use
and inserts it in a table called PLAN_TABLE without executing the SQL statement.
Option 3: Incorrect. The SQL Management Base, or SMB, is a part of the data
dictionary that resides in the SYSAUX tablespace. It stores statement log, plan
histories, and SQL plan baselines, as well as SQL profiles.
Option 4: Incorrect. V$SQL_PLAN_MONITOR displays plan-level monitoring
statistics for each SQL statement found in V$SQL_MONITOR. Each row in
V$SQL_PLAN_MONITOR corresponds to an operation of the execution plan that is
monitored.
Correct answer(s):
Note
Code
SQL> EXPLAIN PLAN
2 SET STATEMENT_ID = 'demo01' FOR
3 SELECT e.last_name, d.department_name
4 FROM hr.employees e, hr.departments d
5 WHERE e.department_id = d.department_id;
Explained.
SQL>
You can also use this code to use the EXPLAIN PLAN command.
Code
EXPLAIN PLAN
FOR
SELECT e.last_name, d.department_name
FROM hr.employees e, hr.departments d
WHERE e.department_id =d.department_id;
There are various methods available to gather execution plans. You are introduced only
to the EXPLAIN PLAN statement. This SQL statement gathers the execution plan of a
SQL statement without executing it, and outputs its result in the PLAN_TABLE table.
Whatever the method to gather and display the explain plan, the basic format and goal
are the same.
However, PLAN_TABLE just shows you a plan that might not be the one chosen by the
optimizer. PLAN_TABLE is automatically created as a global temporary table and is visible
to all users. PLAN_TABLE is the default sample output table into which the EXPLAIN
PLAN statement inserts rows describing execution plans.
PLAN_TABLE is organized in a tree-like structure and you can retrieve that structure by
using both the ID and PARENT_ID columns with a CONNECT BY clause in a SELECT
statement. While a PLAN_TABLE table is automatically set up for each user, you can use
the utlxplan.sql SQL script to manually create a local PLAN_TABLE in your schema and
use it to store the results of EXPLAIN PLAN.
The exact name and location of the utlxplan.sql script depends on your operating system.
On UNIX, it is located in the admin directory. It is recommended 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.
Graphic
The admin directory is located at the path $ORACLE_HOME/rdbms/admin.
Note
If you want an output table with a different name, first create PLAN_TABLE
manually with the utlxplan.sql script, and then rename the table with the RENAME
SQL statement.
Code
Code
SQL> EXPLAIN PLAN SET STATEMENT_ID = 'demo01' FOR SELECT *
FROM emp
2 WHERE ename = 'KING';
Explained.
SQL> SET LINESIZE 130
SQL> SET PAGESIZE 0
SQL> SELECT * FROM table(DBMS_XPLAN.DISPLAY('plan_table',
'demo01', 'typical', null));
Plan hash value: 3956160932
----------------------------------------------------------|Id|Operation
|Name|Rows|Bytes|Cost (%CPU)|Time
|
----------------------------------------------------------| 0|SELECT STATEMENT |
|
1|
37|
3
(0)|00:00:01|
|*1|TABLE ACCESS FULL|EMP |
1|
37|
3
(0)|00:00:01|
----------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------1 - filter("ENAME"='KING')
In the example, you can substitute the name of another plan table instead of
PLAN_TABLE and demo01 represents the statement ID. TYPICAL displays the most
relevant information in the plan: operation ID, name and option, number of rows, bytes,
and optimizer cost.
The last parameter for the DISPLAY function is the one corresponding to
filter_preds. This parameter represents a filter predicate or predicates to restrict the
set of rows selected from the table where the plan is stored. When value is null (the
default), the plan displayed corresponds to the last executed explain plan. This parameter
can reference any column of the table where the plan is stored and can contain any SQL
construct, for example, subquery or function calls.
Code
SQL> EXPLAIN PLAN SET STATEMENT_ID = 'demo01' FOR SELECT *
FROM emp
2 WHERE ename = 'KING';
Explained.
SQL> SET LINESIZE 130
SQL> SET PAGESIZE 0
SQL> SELECT * FROM table(DBMS_XPLAN.DISPLAY('plan_table',
'demo01', 'typical', null));
Plan hash value: 3956160932
----------------------------------------------------------|Id|Operation
|Name|Rows|Bytes|Cost (%CPU)|Time
|
----------------------------------------------------------| 0|SELECT STATEMENT |
|
1|
37|
3
(0)|00:00:01|
|*1|TABLE ACCESS FULL|EMP |
1|
37|
3
(0)|00:00:01|
----------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------1 - filter("ENAME"='KING')
Note
Alternatively, you can run the utlxpls.sql (or utlxplp.sql for parallel queries) script,
located in the admin directory to display the execution plan stored in
PLAN_TABLE. This script uses the DISPLAY table function from the DBMS_XPLAN
package.
The ALL option used with the DISPLAY function in this example allows you to output the
maximum user level information. It includes information displayed with the TYPICAL
level, with additional information such as PROJECTION, ALIAS, and information about
REMOTE SQL, if the operation is distributed.
Code
SQL> SELECT * FROM
table(DBMS_XPLAN.DISPLAY(null,null,'ALL'));
Plan hash value: 3956160932
-----------------------------------------------------------|Id|Operation
|Name|Rows|Bytes|Cost (%CPU)|Time
|
-----------------------------------------------------------| 0|SELECT STATEMENT |
|
1|
37|
3 (0)|00:00:01|
|*1| TABLE ACCESS FULL|EMP |
1|
37|
3 (0)|00:00:01|
-----------------------------------------------------------Query Block Name / Object Alias (identified by operation
id):
-----------------------------------------------------------1 - SEL$1 / EMP@SEL$1
Predicate Information (identified by operation id):
--------------------------------------------------1 - filter("ENAME"='KING')
Column Projection Information (identified by operation id):
----------------------------------------------------------1 - "EMP"."EMPNO"[NUMBER,22], "ENAME"[VARCHAR2,10],
"EMP"."JOB"[VARCHAR2,9], "EMP"."MGR"[NUMBER,22],
"EMP"."HIREDATE"[DATE,7], "EMP"."SAL"[NUMBER,22],
"EMP"."COMM"[NUMBER,22], "EMP"."DEPTNO"[NUMBER,22]
For finer control on the display output, keywords can be added to the format parameter to
customize its default behavior. Each keyword either represents a logical group of plan
table columns (such as PARTITION) or logical additions to the base plan table output
(such as PREDICATE). Format keywords must be separated by either a comma or a
space.
The keywords include
Code
Code
SQL> SELECT * FROM
table(DBMS_XPLAN.DISPLAY(null,null,'ALL'));
Plan hash value: 3956160932
-----------------------------------------------------------|Id|Operation
|Name|Rows|Bytes|Cost (%CPU)|Time
|
-----------------------------------------------------------| 0|SELECT STATEMENT |
|
1|
37|
3 (0)|00:00:01|
|*1| TABLE ACCESS FULL|EMP |
1|
37|
3 (0)|00:00:01|
-----------------------------------------------------------Query Block Name / Object Alias (identified by operation
id):
-----------------------------------------------------------1 - SEL$1 / EMP@SEL$1
Predicate Information (identified by operation id):
--------------------------------------------------1 - filter("ENAME"='KING')
Column Projection Information (identified by operation id):
----------------------------------------------------------1 - "EMP"."EMPNO"[NUMBER,22], "ENAME"[VARCHAR2,10],
"EMP"."JOB"[VARCHAR2,9], "EMP"."MGR"[NUMBER,22],
"EMP"."HIREDATE"[DATE,7], "EMP"."SAL"[NUMBER,22],
"EMP"."COMM"[NUMBER,22], "EMP"."DEPTNO"[NUMBER,22]
PREDICATE
If relevant, the PREDICATE keyword shows the predicate section.
PROJECTION
The PROJECTION keyword shows the projection section, if relevant.
ALIAS
If relevant, the ALIAS keyword shows the "Query Block Name/Object Alias" section.
REMOTE, and
If relevant, the REMOTE keyword shows the information for the distributed query (for
example, remote from serial distribution and remote SQL).
NOTE
The NOTE keyword shows the note section of the explain plan, if relevant.
If the target plan table also stores plan statistics columns (for example, it is a table used
to capture the content of the fixed view V$SQL_PLAN_STATISTICS_ALL), additional
format keywords can be used to specify which class of statistics to display when using the
DISPLAY function. These additional format keywords are IOSTATS, MEMSTATS,
ALLSTATS, and LAST.
Code
Note
Format keywords can be prefixed with the "-" sign to exclude the specified
information. For example, "-PROJECTION" excludes projection information.
The ADVANCED format is available only from Oracle Database 10g, Release 2 and later
versions. This output format includes all sections from the ALL format plus the outline
data that represents a set of hints to reproduce that particular plan. This section may be
useful if you want to reproduce a particular execution plan in a different environment. This
is the same section, which is displayed in the trace file for event 10053.
Code
SELECT plan_table_output FROM
table(DBMS_XPLAN.DISPLAY(null,null,'ADVANCED
-PROJECTION -PREDICATE -ALIAS'));
Plan hash value: 3956160932
-----------------------------------------------------------|Id|Operation
|Name|Rows|Bytes|Cost (%CPU)|Time
|
-----------------------------------------------------------| 0|SELECT STATEMENT |
|
1|
37|
3 (0)|00:00:01|
|*1| TABLE ACCESS FULL|EMP |
1|
37|
3 (0)|00:00:01|
-----------------------------------------------------------Outline Data
------------/*+
BEGIN_OUTLINE_DATA
FULL(@"SEL$1" "EMP"@"SEL$1")
OUTLINE_LEAF(@"SEL$1")
ALL_ROWS
DB_VERSION('11.1.0.6')
OPTIMIZER_FEATURES_ENABLE('11.1.0.6')
IGNORE_OPTIM_EMBEDDED_HINTS
END_OUTLINE_DATA
*/
Note
When the ADVANCED format is used with V$SQL_PLAN, there is one more section
called Peeked Binds (identified by position).
Graphic
The plustrace.sql script is located at $ORACLE_HOME/sqlplus/admin/plustrce.sql.
On some versions and platforms, the plustrace.sql script is run by the database
creation scripts. If this is not the case on your platform, connect as SYSDBA and run the
plustrce.sql script. The PLUSTRACE role contains the select privilege on three V$
views. These privileges are necessary to generate AUTOTRACE statistics.
AUTOTRACE is an excellent diagnostic tool for SQL statement tuning. Because it is purely
declarative, it is easier to use than EXPLAIN PLAN.
Note
The system 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.
You can use this syntax to enable AUTOTRACE in various ways. The options are as
follows:
OFF
You can use the OFF option to disable autotracing SQL statements.
ON
You use the ON option to enable autotracing SQL statements.
TRACE or TRACE[ONLY]
The TRACE or TRACE[ONLY] option enable autotracing SQL statements and suppresses
statement output.
EXPLAIN, and
To display execution plans, but not the statistics, you use the EXPLAIN option.
STATISTICS
The STATISTICS option displays statistics, but does not display execution plans.
If both the EXPLAIN and STATISTICS command options are omitted, execution plans
and statistics are displayed by default.
You can control the report by setting the AUTOTRACE system variable. The following are
some examples:
SET AUTOTRACE ON
This AUTOTRACE report includes both the optimizer execution plan and the SQL statement
execution statistics.
SET AUTOTRACE TRACEONLY EXPLAIN
This AUTOTRACE report shows only the
optimizer execution path without executing the statement.
SET AUTOTRACE ON STATISTICS
This AUTOTRACE report shows the SQL statement execution statistics and rows.
SET AUTOTRACE TRACEONLY, and
This is similar to SET AUTOTRACE ON, but it suppresses the printing of the user's query
output, if any. If STATISTICS is enabled, the query data is still fetched, but not printed.
SET AUTOTRACE OFF
Question
Which AUTOTRACE example should you use to display rows and statistics?
Options:
1.
SET AUTOTRACE ON
2.
3.
4.
Answer
Option 1: Incorrect. This option is used to start tracing statements using
AUTOTRACE. The AUTOTRACE report includes both the optimizer execution plan
and SQL statement execution statistics.
Option 2: Correct. This option is used to display rows and statistics. The
AUTOTRACE report shows SQL statement execution statistics and rows.
Option 3: Incorrect. This option is used to get the plan and statistics only. This is
similar to SET AUTOTRACE ON, but it suppresses the printing of the user's query
output.
Option 4: Incorrect. This option is used to display the execution plan only without
execution. The AUTOTRACE report shows only the optimizer execution path
without executing the statement.
Correct answer(s):
2. SET AUTOTRACE ON STATISTICS
The statistics are recorded by the server when your statement executes and indicates the
system resources required to execute your statement. The results include several
statistics.
Code
SQL> show autotrace
autotrace OFF
SQL> set autotrace traceonly statistics
SQL> SELECT * FROM oe.products;
Code
SQL> show autotrace
autotrace OFF
SQL> set autotrace traceonly statistics
SQL> SELECT * FROM oe.products;
288 rows selected.
Statistics
Code
SQL> show autotrace
autotrace OFF
SQL> set autotrace traceonly statistics
SQL> SELECT * FROM oe.products;
Note
db block gets indicates reads of the current block from the database.
consistent gets are reads of blocks that must satisfy a particular system
change number, or SCN. physical reads indicates reads of blocks from disk.
db block gets and consistent gets are the two statistics that are usually
monitored. These should be low compared to the number of rows retrieved. Sorts
should be performed in memory rather than on disk.
Summary
The execution plan is the output of the optimizer, which is presented to the execution
engine. The execution engine then implements the execution plan. There are various
ways to view the execution plan.
The EXPLAIN PLAN command helps generate the execution plan used to execute a SQL
statement. This command doesn't execute the statement, but produces the plan and
inserts it into a table named PLAN_TABLE. You can retrieve a PLAN_TABLE by using both
the ID and PARENT_ID columns with a CONNECT BY clause in a SELECT statement.
You can use the AUTOTRACE SQL*Plus facility to get a report on the execution plan and
statistics for SQL DML statements. These reports are useful for monitoring and tuning the
performance of the statements. To use AUTOTRACE, a PLAN_TABLE must be available in
your schema, and you must have the PLUSTRACE role.
Table of Contents
| Top of page |
| Learning Objectives |
different hints can cause different cursors. The V$SQL_PLAN view can be used to see the
different plans for different child cursors of the same statement.
Note
Another useful view is V$SQL_PLAN_STATISTICS, which provides the execution
statistics of each operation in the execution plan for each cached cursor. Also the
V$SQL_PLAN_STATISTICS_ALL view concatenates information from
V$SQL_PLAN with execution statistics from V$SQL_PLAN_STATISTICS and
V$SQL_WORKAREA.
The V$SQL_PLAN view contains almost all the PLAN_TABLE columns, in addition to
others. The ADDRESS and HASH_VALUE columns present in PLAN_TABLE have the same
values:
ADDRESS and HASH_VALUE and
The ADDRESS and HASH_VALUE columns can be used to join with V$SQLAREA to add the
cursor specific information.
ADDRESS, HASH_VALUE, and CHILD_NUMBER
The ADDRESS, HASH_VALUE, and CHILD_NUMBER columns can be used to join with
V$SQL to add the child cursor-specific information.
The PLAN_HASH_VALUE column is a numerical representation of the SQL plan for the
cursor. By comparing one PLAN_HASH_VALUE with another, you can easily identify
whether the two plans are the same or not (rather than comparing the two plans line-byline).
Note
Since Oracle Database 10g, SQL_HASH_VALUE in V$SESSION has been
complemented with SQL_ID, which you retrieve in many other V$ views.
SQL_HASH_VALUE is a 32-bit value and deemed to not be unique enough for
large repositories of AWR data. SQL_ID is a 64-bit hash value, which is more
unique, the bottom 32 bits of which are SQL_HASH_VALUE. It is normally
represented as a character string to make it more manageable.
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 include 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 or using the
GATHER_PLAN_STATISTICS hint.
The V$SQL_PLAN_STATISTICS_ALL view contains memory-usage statistics for row
sources that use SQL memory (sort or hash join). This view concatenates information in
V$SQL_PLAN with execution statistics from V$SQL_PLAN_STATISTICS and
V$SQL_WORKAREA.
Graphic
In this example, V$SQLAREA expands into V$SQL in the V$SQLSTATS layer.
V$SQL in the V$SQLSTATS layer is connected V$SQL_WORKAREA,
V$SQL_PLAN, and V$SQL_PLAN_STATISTICS in the
V$SQL_PLAN_STATISTICS_ALL layer. V$SQL_PLAN contains estimated
statistics for each row source and V$SQL_PLAN_STATISTICS contains execution
statistics for each row source.
V$SQLAREA provides statistics on SQL statements that are in memory, parsed, and ready
for execution:
SQL_ID and
SQL_ID is the SQL identifier of the parent cursor in the library cache.
VERSION_COUNT
VERSION_COUNT is the number of child cursors that are present in the cache under this
parent.
V$SQL lists statistics on shared SQL areas and contains one row for each child of the
original SQL text entered:
ADDRESS
ADDRESS represents the address of the handle to the parent for this cursor.
HASH_VALUE
HASH_VALUE contains the value of the parent statement in the library cache.
SQL_ID
The SQL identifier of the parent cursor in the library cache is represented by SQL_ID.
PLAN_HASH_VALUE, and
What are the top 10 work areas that require the most cache area?
For work areas allocated in the AUTO mode, what percentage of work areas run using maximum
memory?
V$SQLSTATS displays basic performance statistics for SQL cursors, with each row
representing the data for a unique combination of SQL text and optimizer plan (that is,
unique combination of SQL_ID and PLAN_HASH_VALUE). The column definitions for
columns in V$SQLSTATS are identical to those in the V$SQL and V$SQLAREA views.
However, the V$SQLSTATS view differs from V$SQL and V$SQLAREA in that it is faster,
more scalable, and has a greater data retention (the statistics may still appear in this
view, even after the cursor has been aged out of the shared pool).
Note
V$SQLSTATS contains a subset of columns that appear in V$SQL and
V$SQLAREA.
Question
Which statements accurately describe the V$SQL_PLAN view?
Options:
1.
2.
3.
It provides a way of examining the execution plan for cursors that are still in the
library cache
4.
It provides the execution statistics of each operation in the execution plan for each
cached cursor
Answer
Option 1: Correct. EXPLAIN PLAN shows a theoretical plan that can be used if
this statement were to be executed, whereas V$SQL_PLAN contains the actual
plan used.
Option 2: Incorrect. The V$SQL_PLAN_STATISTICS_ALL view concatenates
information from V$SQL_PLAN with execution statistics from
V$SQL_PLAN_STATISTICS and V$SQL_WORKAREA.
Option 3: Correct. This view provides a way of examining the execution plan for
cursors that are still in the library cache, and shows the plan for a cursor rather
than for all cursors associated with a SQL statement.
Option 4: Incorrect. V$SQL_PLAN_STATISTICS provides the execution statistics
of each operation in the execution plan for each cached cursor.
Correct answer(s):
1. It is similar to the PLAN_TABLE, but contains the actual plan used
3. It provides a way of examining the execution plan for cursors that are still in the
library cache
Graphic
The SQL_ID parameter that is being passed is the following: 47ju6102uvq5q.
Code
SELECT PLAN_TABLE_OUTPUT FROM
TABLE(DBMS_XPLAN.DISPLAY_CURSOR('47ju6102uvq5q'));
SQL_ID 47ju6102uvq5q, child number 0
------------------------------------SELECT e.last_name, d.department_name
FROM hr.employees e, hr.departments d WHERE
e.department_id =d.department_id
Plan hash value: 2933537672
------------------------------------------------------------------|Id|Operation
|Name
|Rows|Bytes|
Cost (%CPU|
------------------------------------------------------------------| 0|SELECT STATEMENT
|
|
|
|
6 (100|
| 1| MERGE JOIN
|
| 106| 2862|
6
(17|
| 2| TABLE ACCESS BY INDEX ROWID|
DEPARTMENTS| 27| 432|
2
(0|
| 3|
INDEX FULL SCAN
|DEPT_ID_PK
| 27|
|
1
(0|
|*4| SORT JOIN
|
| 107| 1177|
4
(25|
| 5|
TABLE ACCESS FULL
|EMPLOYEES
| 107| 1177|
3
(0|
------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------4 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
filter("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
24 rows selected.
You can pass the value of SQL_ID for the statement as a parameter to obtain the
execution plan for a given statement. SQL_ID is the SQL_ID of the SQL statement in the
cursor cache.
You can retrieve the appropriate value by querying the SQL_ID column in V$SQL or
V$SQLAREA. Alternatively, you could select the PREV_SQL_ID column for a specific
session out of V$SESSION. This parameter defaults to null in which case the plan of the
last cursor executed by the session is displayed.
Graphic
The SQL_ID parameter that is being passed is the following: 47ju6102uvq5q.
Code
SELECT PLAN_TABLE_OUTPUT FROM
TABLE(DBMS_XPLAN.DISPLAY_CURSOR('47ju6102uvq5q'));
SQL_ID 47ju6102uvq5q, child number 0
------------------------------------SELECT e.last_name, d.department_name
FROM hr.employees e, hr.departments d WHERE
e.department_id =d.department_id
Plan hash value: 2933537672
------------------------------------------------------------------|Id|Operation
|Name
|Rows|Bytes|
Cost (%CPU|
------------------------------------------------------------------| 0|SELECT STATEMENT
|
|
|
|
6 (100|
| 1| MERGE JOIN
|
| 106| 2862|
6
(17|
| 2| TABLE ACCESS BY INDEX ROWID|
DEPARTMENTS| 27| 432|
2
(0|
| 3|
INDEX FULL SCAN
|DEPT_ID_PK
| 27|
|
1
(0|
|*4| SORT JOIN
|
| 107| 1177|
4
(25|
| 5|
TABLE ACCESS FULL
|EMPLOYEES
| 107| 1177|
3
(0|
-------------------------------------------------------------------
Code
SELECT e.last_name, d.department_name
FROM hr.employees e, hr.departments d
WHERE e.department_id =d.department_id;
SELECT SQL_ID, SQL_TEXT FROM V$SQL
WHERE SQL_TEXT LIKE '%SELECT e.last_name,%' ;
13saxr0mmz1s3 SELECT SQL_id, sql_text from v$SQL
47ju6102uvq5q SELECT e.last_name, d.department_name
You can also pass the CHILD_NUMBER parameter to the
DBMS_XPLAN.DISPLAY_CURSOR()function. CHILD_NUMBER is the child number of the
cursor to display. If not supplied, the execution plan of all cursors matching the supplied
SQL_ID parameter is displayed. CHILD_NUMBER can be specified only if SQL_ID is
specified.
Code
SELECT PLAN_TABLE_OUTPUT FROM
TABLE(DBMS_XPLAN.DISPLAY_CURSOR('47ju6102uvq5q'));
SQL_ID 47ju6102uvq5q, child number 0
------------------------------------SELECT e.last_name, d.department_name
FROM hr.employees e, hr.departments d WHERE
e.department_id =d.department_id
Plan hash value: 2933537672
------------------------------------------------------------------|Id|Operation
|Name
|Rows|Bytes|
Cost (%CPU|
-------------------------------------------------------------------
| 0|SELECT STATEMENT
|
|
|
|
6 (100|
| 1| MERGE JOIN
|
| 106| 2862|
6
(17|
| 2| TABLE ACCESS BY INDEX ROWID|
DEPARTMENTS| 27| 432|
2
(0|
| 3|
INDEX FULL SCAN
|DEPT_ID_PK
| 27|
|
1
(0|
|*4| SORT JOIN
|
| 107| 1177|
4
(25|
| 5|
TABLE ACCESS FULL
|EMPLOYEES
| 107| 1177|
3
(0|
------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------4 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
filter("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
24 rows selected.
The DBMS_XPLAN.DISPLAY_CURSOR()function can also accept the FORMAT parameter.
The FORMAT parameter controls the level of detail for the plan. In addition to the standard
values (BASIC, TYPICAL, SERIAL, and ALL), there are additional supported values to
display run-time statistics for the cursor:
Code
SELECT PLAN_TABLE_OUTPUT FROM
TABLE(DBMS_XPLAN.DISPLAY_CURSOR('47ju6102uvq5q'));
SQL_ID 47ju6102uvq5q, child number 0
------------------------------------SELECT e.last_name, d.department_name
FROM hr.employees e, hr.departments d WHERE
e.department_id =d.department_id
Plan hash value: 2933537672
------------------------------------------------------------------|Id|Operation
|Name
|Rows|Bytes|
Cost (%CPU|
------------------------------------------------------------------| 0|SELECT STATEMENT
|
| 1| MERGE JOIN
(100|
|
| 106| 2862|
6
(17|
| 2| TABLE ACCESS BY INDEX ROWID|
DEPARTMENTS| 27| 432|
2
(0|
| 3|
INDEX FULL SCAN
|DEPT_ID_PK
| 27|
|
1
(0|
|*4| SORT JOIN
|
| 107| 1177|
4
(25|
| 5|
TABLE ACCESS FULL
|EMPLOYEES
| 107| 1177|
3
(0|
------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------4 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
filter("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
24 rows selected.
IOSTATS
Assuming that the basic plan statistics are collected when SQL statements are executed
(either by using the GATHER_PLAN_STATISTICS hint or by setting the
statistics_level parameter to ALL), the IOSTATS format shows I/O statistics for ALL
(or only for LAST) executions of the cursor.
MEMSTATS
Assuming that the Program Global Area, or PGA, memory management is enabled (that is,
the pga_aggregate_target parameter is set to a nonzero value), the MEMSTATS format
allows to display memory management statistics (for example, execution mode of the
operator, how much memory was used, number of bytes spilled to disk, and so on.) These
statistics only apply to memory-intensive operations, such as hash joins, sort, or some
bitmap operators.
ALLSTATS, and
It is a shortcut for IOSTATS MEMSTATS.
LAST
By default, plan statistics are shown for all executions of the cursor. The LAST keyword
can be specified to see only the statistics for the last execution.
object statistics that determine both access and usage statistics of database segments
time-model statistics based on time usage for activities, displayed in the V$SYS_TIME_MODEL
and V$SESS_TIME_MODEL views
some of the system and session statistics collected in the V$SYSSTAT and V$SESSTAT views
SQL statements that produce the highest load on the system, based on criteria, such as elapsed
time, CPU time, buffer gets, and
Active Session History, or ASH, statistics, representing the history of recent sessions
The database automatically generates snapshots of the performance data once every
hour and collects the statistics in the workload repository. The data in the snapshot
interval is then analyzed by ADDM.
The ADDM compares the differences between snapshots to determine which SQL
statements to capture based on the effect on the system load. This reduces the number
of SQL statements that need to be captured over time.
Note
By using PL/SQL packages such as DBMS_WORKLOAD_REPOSITORY or Oracle
Enterprise Manager, you can mange the frequency and retention period of SQL
that is stored in the AWR.
Although the primary interface for managing the AWR is Enterprise Manager, monitoring
functions can be managed with procedures in the DBMS_WORKLOAD_REPOSITORY
package.
Snapshots are automatically generated for an Oracle database; however, you can use
DBMS_WORKLOAD_REPOSITORY procedures to manually create, drop, and modify the
snapshots and baselines that are used by the ADDM.
Snapshots and baselines are sets of historical data for specific time periods that are used
for performance comparisons. To invoke these procedures, a user must be granted the
DBA role.
You can manually create snapshots with the CREATE_SNAPSHOT procedure if you want
to capture statistics at times different than those of the automatically generated
snapshots.
In this CREATE_SNAPSHOT procedure example, a snapshot for the instance is created
immediately with the flush level specified to the default flush level of TYPICAL. You can
view this snapshot in the DBA_HIST_SNAPSHOT view.
Code
Exec DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT ('ALL');
You can drop a range of snapshots using the DROP_SNAPSHOT_RANGE procedure. To
view a list of the snapshot IDs along with database IDs, check the DBA_HIST_SNAPSHOT
view. For example, you can drop the range of snapshots provided in this example.
In this example, the range of snapshot IDs to drop is specified from 22 to 32. The optional
database identifier is 3310949047. If you do not specify a value for dbid, the local
database identifier is used as the default value.
ASH data that belongs to the time period specified by the snapshot range is also purged
when the DROP_SNAPSHOT_RANGE procedure is called.
Code
Exec DBMS_WORKLOAD_REPOSITORY.DROP_SNAPSHOT_RANGE (low_snap_id =>
22, high_snap_id => 32, dbid => 3310949047);
You can adjust the interval and retention of snapshot generation for a specified database
ID. However, note that this can affect the precision of the Oracle diagnostic tools. The
INTERVAL setting specifies how often (in minutes) snapshots are automatically
generated. The RETENTION setting specifies how long (in minutes) snapshots are stored
in the workload repository. To adjust the settings, use the
MODIFY_SNAPSHOT_SETTINGS procedure.
In this example, the retention period is specified as 43,200 minutes (30 days), and the
interval between each snapshot is specified as 30 minutes. If NULL is specified, the
existing value is preserved. The optional database identifier is 3310949047. If you do not
specify a value for dbid, the local database identifier is used as the default value. You
can check the current settings for your database instance with the
DBA_HIST_WR_CONTROL view.
Code
Exec DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(
-retention
=> 43200, interval => 30, dbid => 3310949047);
You can view the AWR data on Oracle Enterprise Manager screens or in AWR reports.
However, you can also view the statistics directly using
V$ACTIVE_SESSION_HISTORY and
The V$ACTIVE_SESSION_HISTORY view displays active database session activity,
sampled once every second.
V$ metric views
V$ metric views provide metric data to track the performance of the system. The metric
views are organized into various groups, such as event, event class, system, session,
service, file, and tablespace metrics. These groups are identified in the V$METRICGROUP
view.
The DBA_HIST views contain historical data stored in the database. This group of views
include
DBA_HIST_ACTIVE_SESS_HISTORY
DBA_HIST_ACTIVE_SESS_HISTORY displays the history of the contents of the sampled
in memory active session history for recent system activity.
DBA_HIST_BASELINE
Information about the baselines captured in the system is displayed in
DBA_HIST_BASELINE.
DBA_HIST_DATABASE_INSTANCE
To display information about the database environment, you can use
DBA_HIST_DATABASE_INSTANCE.
DBA_HIST_SNAPSHOT
DBA_HIST_SNAPSHOT contains information about snapshots in the system.
DBA_HIST_SQL_PLAN, and
SQL execution plans are retrieved by DBA_HIST_SQL_PLAN.
DBA_HIST_WR_CONTROL
DBA_HIST_WR_CONTROL displays the settings for controlling AWR.
Question
Identify the statements that accurately describe AWR.
Options:
1.
2.
3.
You can manage the frequency and retention period of SQL that is stored in the
AWR
4.
You can view AWR data on OEM screens or AWR reports only
Answer
Option 1: Correct. The database automatically generates snapshots of the
performance data once every hour and collects the statistics in the workload
repository.
Option 2: Incorrect. The AWR automatically collects, processes, and maintains
system-performance statistics for problem-detection and self-tuning purposes and
stores the statistics persistently in the database.
Option 3: Correct. By using PL/SQL packages, such as
DBMS_WORKLOAD_REPOSITORY or OEM, you can mange the frequency and
retention period of SQL that is stored in the AWR.
Option 4: Incorrect. You can use OEM and AWR reports to view AWR data.
However, you can also query V$ACTIVE_SESSION_HISTORY, the V$ metric
views, and the DBA_HIST views.
Correct answer(s):
1. It automatically generates snapshots of performance data
3. You can manage the frequency and retention period of SQL that is stored in the
AWR
You can use the DBMS_XPLAN.DISPLAY_AWR() function to display all stored plans in
the AWR.
In this example, you pass in a SQL_ID as an argument. SQL_ID is the SQL_ID of the
SQL statement in the cursor cache.
Code
SQL> SELECT PLAN_TABLE_OUTPUT FROM TABLE
(DBMS_XPLAN.DISPLAY_AWR('454rug2yva18w'));
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------SQL_ID 454rug2yva18w
Code
SELECT tf.* FROM DBA_HIST_SQLTEXT ht, table
(DBMS_XPLAN.DISPLAY_AWR(ht.sql_id,null, null, 'ALL' ))
tf
WHERE ht.sql_text like '%JF%';
You follow five steps to complete this example.
Code
SQL> SELECT /* example */ * FROM hr.employees NATURAL
JOIN hr.departments;
SQL> SELECT sql_id, sql_text FROM v$SQL
WHERE sql_text
LIKE '%example%';
Code
SQL> @$ORACLE_HOME/rdbms/admin/awrsqrpt
Specify the Report Type
Would you like an HTML report, or a plain text report?
Specify the number of days of snapshots to choose from
Specify the Begin and End Snapshot Ids
Specify the SQL Id
Enter value for sql_id: 6g1p4s9ra6ag8
Specify the Report Name
You can display the plan information in AWR by using the DISPLAY_AWR table function in
the DBMS_XPLAN PL/SQL package.
For example, this displays the plan information for a SQL_ID in AWR.
You can retrieve the appropriate value for the SQL statement of interest by querying the
SQL_ID in DBA_HIST_SQLTEXT column.
Code
SELECT * FROM
table(DBMS_XPLAN.DISPLAY_AWR('6g1p4s9ra6ag8'));
Summary
The information in V$SQL_PLAN view provides a way of examining the execution plan for
cursors that are still in the library cache. The V$SQL_PLAN_STATISTICS view provides
the execution statistics of each operation in the execution plan for each cached cursor.
All the statistics displayed in V$SQL are updated at the end of query execution. The
V$SQL_PLAN_STATISTICS view provides execution statistics, and the ADDRESS and
HASH_VALUE columns can be used to join with V$SQLAREA. The ADDRESS,
HASH_VALUE, and CHILD_NUMBER columns can be used to join with V$SQL.
The AWR automatically collects, processes, and maintains system performance statistics
and stores them persistently in the database.
Table of Contents
| Top of page |
| Learning Objectives |
dynamic performance V$SQL_MONITOR view. This entry tracks key performance metrics
collected for the execution, including the elapsed time, CPU time, number of reads and
writes, I/O wait time, and various other wait times. These statistics are refreshed in near
real time as the statement executes, generally once every second.
After the execution ends, monitoring information is not deleted immediately, but is kept in
the V$SQL_MONITOR view for at least one minute. The entry is eventually deleted so its
space can be reclaimed as new statements are monitored.
The V$SQL_MONITOR and V$SQL_PLAN_MONITOR views can be used in conjunction
with the following views to get additional information about the execution that is
monitored:
V$SQL
V$SQL_PLAN
V$ACTIVE_SESSION_HISTORY
V$SESSION_LONGOPS, and
V$SESSION
Instead, you can use the SQL Monitoring Report to view SQL monitoring data. The SQL
monitoring report is also available in a GUI version through Enterprise Manager.
In this example, it is assumed that you SELECT from SALES from a different session than
the one used to print the SQL monitoring report.
Code
SQL> SELECT count(*) FROM sales;
In the SQL Monitoring Report, the DBMS_SQLTUNE.REPORT_SQL_MONITOR function
accepts several input parameters to specify the execution, the level of detail in the report,
and the report type (TEXT, HTML, or XML). By default, a text report is generated for the
last execution that was monitored if no parameters are specified.
After the SELECT statement is started, and while it executes, you print the SQL
monitoring report from a second session. From the report, you can see that the SELECT
statement executes currently.
Code
SQL>
SQL>
SQL>
SQL>
Code
SQL>
SQL>
SQL>
SQL>
Note
The report also includes some important statistics calculated so far.
The SQL Monitoring Report then displays the execution path currently used by your
statement. SQL monitoring gives you the display of the current operation that executes in
the plan. This enables you to detect parts of the plan that are the most time-consuming,
so that you can focus your analysis on those parts. The running operation is marked by
an arrow in the Id column of the report.
The Time Active(s) column shows how long the operation has been active (the delta in
seconds between the first and the last active time).
Code
SQL Plan Monitoring Details
============================================================
========================
| Id
|
Operation
| Name | Rows
| Cost
|
Time
| Start |
|
|
|
| (Estim)
|
| Active(s) | Active |
============================================================
========================
|
0 | SELECT STATEMENT
|
|
| 78139
|
|
|
|
1 |
SORT AGGREGATE
|
|
1
|
|
|
|
| -> 2 |
TABLE ACCESS FULL | SALES | 53984K | 78139
|
23 |
+1 |
|
|
|
|
|
|
|
|
============================================================
========================
============================================================
======================
Starts |
Rows
| Activity |
Activity Detail
| Progress |
|
(Actual) | (percent) |
(sample #)
|
|
1
|
|
|
|
|
1
|
|
|
|
|
1 |
42081K |
100.00 | Cpu (4)
| 74%
|
============================================================
======================
The Start Active column shows, in seconds, when the operation in the execution plan
started relative to the SQL statement execution start time. In this report, the table access
full operation at Id 2 was the first to start (+1s Start Active) and ran for the first 23
seconds so far.
The Starts column shows the number of times the operation in the execution plan was
executed.
The Rows (Actual) column indicates the number of rows produced, and the Rows (Estim)
column shows the estimated cardinality from the optimizer.
Code
Code
SQL Plan Monitoring Details
============================================================
========================
| Id
|
Operation
| Name | Rows
| Cost
|
Time
| Start |
|
|
|
| (Estim)
|
| Active(s) | Active |
============================================================
========================
|
0 | SELECT STATEMENT
|
|
| 78139
|
|
|
|
1 |
SORT AGGREGATE
|
|
1
|
|
|
|
| -> 2 |
TABLE ACCESS FULL | SALES | 53984K | 78139
|
23 |
+1 |
|
|
|
|
|
|
|
|
============================================================
========================
============================================================
======================
Starts |
Rows
| Activity |
Activity Detail
| Progress |
|
(Actual) | (percent) |
(sample #)
|
|
1
|
|
|
|
|
1
|
|
|
|
|
1 |
42081K |
100.00 | Cpu (4)
| 74%
|
============================================================
======================
The last column, Progress, shows progress monitoring information for the operation from
the V$SESSION_LONGOPS view. According to this report, so far, the TABLE ACCESS
FULL operation is 74% complete. This column only appears in the report after a certain
amount of time, and only for the instrumented row sources.
Code
Note
The SQL Plan Monitoring Details report can also contain the Memory and Temp
columns. These indicate the amount of memory and temporary space consumed
by corresponding operation of the execution plan.
Question
You are examining a SQL monitoring report. The Time Active(s) column displays a
value of 23. What does this number present?
Options:
1.
2.
3.
The number of times the operation in the execution plan was executed
4.
When the operation in the execution plan started relative to the SQL statement
execution start time
Answer
Option 1: Correct. The Time Active(s) column shows how long the operation has
been active the delta in seconds between the first and the last active time.
Option 2: Incorrect. The Rows (Actual) column shows the number of rows
produced.
Option 3: Incorrect. The Starts column shows the number of times the operation
in the execution plan was executed.
Option 4: Incorrect. The Start Active column shows, in seconds, when the
operation in the execution plan started relative to the SQL statement execution
start time.
Correct answer(s):
1. How long the operation has been active
Graphic
There are four levels in the tree format. The node Root/Parent is on Level 1. This
node is divided into two subnodes on Level 2. These subnodes are named
Parent/Child. The Parent/Child subnode on the left is executed first. The two
Parent/Child subnodes are divided into two subnodes each on Level 3. Both of
their subnodes are named Child/Leaf and Parent/Child. The left Parent/Child
subnode on Level 3 is further divided into two subnodes named Child/Leaf. The
right Parent/Child subnode on Level 3 is divided into one subnode named
Child/Leaf.
In PLAN_TABLE and V$SQL_PLAN, the important elements to retrieve the tree structure
are the ID, PARENT_ID, and POSITION columns. In a trace file, these columns
correspond to the id, pid, and pos fields, respectively.
One way to read an execution plan is by converting it into a graph that has a tree
structure. You can start from the top, with id= 1, which is the root node in the tree. Next,
you must find the operations that feed this root node. That is accomplished by operations,
which have parent_id, or pid, with value 1.
To draw plan as a tree, do the following:
1. take the ID with the lowest number and place it at the top
2. look for rows which have a PID (parent) equal to this value
3. place these in the tree below the Parent according to their POS values from the lowest to the highest,
ordered from left to right, and
4. move down to the next ID after all the IDs for a parent have been found, and repeat the process, finding
new rows with the same PID
The first thing to determine in an explain plan is which node is executed first. With
complicated plans it is difficult to do this and also difficult to follow the steps through to the
end. Large plans are exactly the same as smaller ones, but with more entries.
The same basic rules apply. You can always collapse the plan to hide a branch of the tree
which does not consume much of the resources.
The standard explain plan interpretation is as follows:
1. Start at the top.
2. Move down the row sources until you get to one that produces data, but does not consume any. This is
the start row source.
3. Look at the siblings of this row source. These row sources are executed next.
4. After the children are executed, the parent is executed next.
5. Now that this parent and its children are completed, work back up the tree, and look at the siblings of the
parent row source and its parents. Execute as before.
6. Move back up the plan until all row sources are executed.
The standard tree interpretation is as follows:
1. Start at the top.
2. Move down the tree to the left until you reach the left node. This is executed first.
3. Look at the siblings of this row source. These row sources are executed next.
4. After the children are executed, the parent is executed next.
5. Now that this parent and its children are completed, work back up the tree, and look at the siblings of the
parent row source and its parents. Execute as before.
6. Move back up the tree until all row sources are exhausted.
Note
If you remember the few basic rules of explain plans and with some experience,
you can read most plans easily.
Question
Sequence the steps you take to interpret a standard explain plan.
Options:
A.
Start at the top and move down row sources until you get to one that produces data
but does not consume any
B.
C.
Work back up the tree and look at the siblings of the parent row source and its
parents and execute as before
D.
Move back up the plan until all row sources are exhausted
Answer
Correct answer(s):
Start at the top and move down row sources until you get to one that
produces data but does not consume any is ranked as the first step.
The first step in interpreting a standard explain plan is to start at the top and
then move down the row sources until you get to one that produces data, but
does not consume any. This is the start row source.
Look at the siblings of the start row source is ranked as the second step.
The second step in interpreting a standard explain plan is to look through the
siblings of the start row source, as these are the row sources executed next.
Work back up the tree and look at the siblings of the parent row source and
its parents and execute as before is ranked as the third step.
The third step in interpreting a standard explain plan is to work back up the
tree and look at the siblings of the parent row source and its parents. After
the children are executed, the parent is executed next.
Move back up the plan until all row sources are exhausted is ranked as the
final step.
The final step in interpreting a standard explain plan is to move back up the
plan until all row sources are exhausted.
You start with an example query to illustrate how to interpret an execution plan. The query
with its associated execution plan and the same plan in the tree format is shown in this
example.
Graphic
The example query is the following:
SELECT /*+ RULE */ ename,job,sal,dname
FROM emp,dept
WHERE dept.deptno=emp.deptno and not exists(SELECT *
FROM salgrade
WHERE emp.sal between losal and hisal);
The output is displayed in a tabular format with Id, Operation, Name as columns.
The query tries to find employees who have salaries outside the range of salaries in the
salary grade table. The query is a SELECT statement from two tables with a subquery
based on another table to check the salary grades.
Code
SELECT /*+ RULE */ ename,job,sal,dname
FROM emp,dept
WHERE dept.deptno=emp.deptno and not exists(SELECT *
FROM salgrade
WHERE emp.sal
between losal and hisal);
-------------------------------------------------| Id | Operation
| Name
|
-------------------------------------------------|
0 | SELECT STATEMENT
|
|
|* 1 | FILTER
|
|
|
2 |
NESTED LOOPS
|
|
|
3 |
TABLE ACCESS FULL
| EMP
|
|
4 |
TABLE ACCESS BY INDEX ROWID| DEPT
|
|* 5 |
INDEX UNIQUE SCAN
| PK_DEPT |
|* 6 |
TABLE ACCESS FULL
| SALGRADE |
-------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------1 - filter( NOT EXISTS
(SELECT 0 FROM "SALGRADE" "SALGRADE" WHERE
"HISAL">=:B1 AND "LOSAL"<=:B2))
5 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")
6 - filter("HISAL">=:B1 AND "LOSAL"<=:B2)
This is the execution order for the query:
3
The plan starts with a full table scan of EMP (ID=3).
5
The rows are passed back to the controlling nested loops join step (ID=2), which uses
them to execute the lookup of rows in the PK_DEPT index in ID=5.
4
The ROWIDs from the index are used to lookup the other information from the DEPT table in
ID=4.
2
ID=2, the nested loops join step, is executed until completion.
6, and
After ID=2 has exhausted its row sources, a full table scan of SALGRADE in ID=6 (at the
same level in the tree as ID=2, therefore, its sibling) is executed.
1
This is used to filter the rows from ID2 and ID6.
The children are executed before parents, so although structures for joins must be set up
before the child execution, the children are notated as executed first.
Perhaps the easiest way is to consider it as the order in which execution completes, so
for the NESTED LOOPS join at ID=2, the two children {ID=3 and ID=4 (together with its
child)} must have completed their execution before ID=2 can be completed.
In this example, a plan dump from V$SQL_PLAN with STATISTICS_LEVEL is set to ALL.
This report includes some important additional information compared to the output of the
EXPLAIN PLAN command:
Code
SQL> ALTER SESSION SET statistics_level=ALL;
Session altered.
SQL> SELECT /*+ RULE to make sure it reproduces 100% */
ename,job,sal,dname
FROM emp,dept WHERE dept.deptno = emp.deptno AND NOT EXISTS
(SELECT * FROM salgrade
WHERE emp.sal BETWEEN losal AND hisal);
no rows selected
SQL> SELECT * FROM
table(DBMS_XPLAN.DISPLAY_CURSOR(null,null,'TYPICAL IOSTATS
LAST'));
SQL_ID 274019myw3vuf, child number 0
------------------------------------
Plan hash value: 1175760222
------------------------------------------------------------------------------| Id | Operation
| Name
| Starts
| A-Rows | Buffers |
------------------------------------------------------------------------------|* 1 | FILTER
|
|
1
|
0 |
61 |
|
2 |
NESTED LOOPS
|
|
1
|
14 |
25 |
|
3 |
TABLE ACCESS FULL
| EMP
|
1
|
14 |
7 |
|
4 |
TABLE ACCESS BY INDEX ROWID | DEPT
|
14
|
14 |
18 |
|* 5 |
INDEX UNIQUE SCAN
| PK_DEPT |
14
|
14 |
4 |
|* 6 |
TABLE ACCESS FULL
| SALGRADE |
12
|
12 |
36 |
------------------------------------------------------------------------------
A-Rows corresponds to the number of rows produced by the corresponding row source
Buffers corresponds to the number of consistent reads done by the row source, and
Starts indicates how many times the corresponding operation was processed
For each row from the EMP table, the system gets its ENAME, SAL, JOB, and DEPTNO.
Then the system accesses the DEPT table by its unique index (PK_DEPT) to get DNAME
using DEPTNO from the previous result set.
The TABLE ACCESS FULL operation on the EMP table (ID=3) is started once. However,
operations from ID 5 and 4 are started 14 times; once for each EMP row. At this step
(ID=2), the system gets all ENAME, SAL, JOB, and DNAME.
Code
SQL> ALTER SESSION SET statistics_level=ALL;
Session altered.
SQL> SELECT /*+ RULE to make sure it reproduces 100% */
ename,job,sal,dname
FROM emp,dept WHERE dept.deptno = emp.deptno AND NOT EXISTS
(SELECT * FROM salgrade
WHERE emp.sal BETWEEN losal AND hisal);
no rows selected
SQL> SELECT * FROM
table(DBMS_XPLAN.DISPLAY_CURSOR(null,null,'TYPICAL IOSTATS
LAST'));
SQL_ID 274019myw3vuf, child number 0
------------------------------------
Plan hash value: 1175760222
------------------------------------------------------------------------------| Id | Operation
| Name
| Starts
| A-Rows | Buffers |
------------------------------------------------------------------------------|* 1 | FILTER
|
|
1
|
0 |
61 |
|
2 |
NESTED LOOPS
|
|
1
|
14 |
25 |
|
3 |
TABLE ACCESS FULL
| EMP
|
1
|
14 |
7 |
|
4 |
TABLE ACCESS BY INDEX ROWID | DEPT
|
14
|
14 |
18 |
|* 5 |
INDEX UNIQUE SCAN
| PK_DEPT |
14
|
14 |
4 |
|* 6 |
TABLE ACCESS FULL
| SALGRADE |
12
|
12 |
36 |
------------------------------------------------------------------------------The system now must filter out employees who have salaries outside the range of
salaries in the salary grade table. To do that, for each row from ID=2, the system
accesses the SALGRADE table using a FULL TABLE SCAN operation to check if the
employees salary is outside the salary range.
This operation only needs to be done 12 times in this case because at run time the
system does the check for each distinct salary, and there are 12 distinct salaries in the
EMP table.
Code
SQL> ALTER SESSION SET statistics_level=ALL;
Session altered.
SQL> SELECT /*+ RULE to make sure it reproduces 100% */
ename,job,sal,dname
FROM emp,dept WHERE dept.deptno = emp.deptno AND NOT EXISTS
(SELECT * FROM salgrade
WHERE emp.sal BETWEEN losal AND hisal);
no rows selected
SQL> SELECT * FROM
table(DBMS_XPLAN.DISPLAY_CURSOR(null,null,'TYPICAL IOSTATS
LAST'));
SQL_ID 274019myw3vuf, child number 0
-------------------------------------
Plan hash value: 1175760222
------------------------------------------------------------------------------| Id | Operation
| Name
| Starts
| A-Rows | Buffers |
------------------------------------------------------------------------------|* 1 | FILTER
|
|
1
|
0 |
61 |
|
2 |
NESTED LOOPS
|
|
1
|
14 |
25 |
|
3 |
TABLE ACCESS FULL
| EMP
|
1
|
14 |
7 |
|
4 |
TABLE ACCESS BY INDEX ROWID | DEPT
|
14
|
14 |
18 |
|* 5 |
INDEX UNIQUE SCAN
| PK_DEPT |
14
|
14 |
4 |
|* 6 |
TABLE ACCESS FULL
| SALGRADE |
12
|
12 |
36 |
------------------------------------------------------------------------------In this second example, the query retrieves names, department names, and addresses
for employees whose departments are located in Seattle and who have managers.
Graphic
The example query is the following:
SQL> select /*+ USE_NL(d) use_nl(m) */ m.last_name as dept_manager
2 , d.department_name
3 , l.street_address
4 from hr.employees m join
5 hr.departments d on (d.manager_id = m.employee_id)
6 natural join
7 hr.locations l
8 where l.city = 'Seattle';
0 SELECT STATEMENT
1 0 NESTED LOOPS
2 1 NESTED LOOPS
3 2 TABLE ACCESS BY INDEX ROWID LOCATIONS
4 3 INDEX RANGE SCAN LOC_CITY_IX
5 2 TABLE ACCESS BY INDEX ROWID DEPARTMENTS
6 5 INDEX RANGE SCAN DEPT_LOCATION_IX
The inner nested loops is executed first using LOCATIONS as the driving table, using an index
access on the CITY column. This is because you search for departments in Seattle only.
The result is joined with the DEPARTMENTS table, using the index on the LOCATION_ID join
column; the result of this first join operation is the driving row source for the second nested loops
join.
The second join probes the index on the EMPLOYEE_ID column of the EMPLOYEES table. The
system can do that because it knows (from the first join) the employee ID of all managers of
departments in Seattle. Note that this is a unique scan because it is based on the primary key.
Finally, the EMPLOYEES table is accessed to retrieve the last name.
In this example, try to find the order in which the plan is executed and deduce what is the
join order (order in which the system joins tables). Again, ID is in the first column and PID
in the second column. The position is reflected by the indentation.
It is important to recognize what the join order of an execution plan is, to be able to find
your plan into a 10053 event trace file.
Code
SELECT /*+ ORDERED use_hash(b) swap_join_inputs(c) */
max(a.i)
FROM t1 a, t2 b, t3 c
WHERE a.i = b.i AND a.i = c.i;
0
1
2
3
4
5
6
1
2
2
4
4
SELECT STATEMENT
SORT AGGREGATE
HASH JOIN
TABLE ACCESS FULL T3
HASH JOIN
TABLE ACCESS FULL T1
TABLE ACCESS FULL T2
Code
SELECT /*+ ORDERED use_hash(b) swap_join_inputs(c) */
max(a.i)
FROM t1 a, t2 b, t3 c
WHERE a.i = b.i AND a.i = c.i;
0
1
2
3
4
5
6
1
2
2
4
4
SELECT STATEMENT
SORT AGGREGATE
HASH JOIN
TABLE ACCESS FULL T3
HASH JOIN
TABLE ACCESS FULL T1
TABLE ACCESS FULL T2
the system first hashes the T3 table (Operation ID=3) into memory
the system outputs the maximum value from the previous result set
In conclusion, the execution order is : 3 5 6 4 2 1. The join order is: T1 T2
T3. You can also use Enterprise Manager to understand execution plans, especially
because it displays the Order column.
Note
A special hint was used to make sure T3 would be first in the plan.
Summary
By default, SQL monitoring is automatically started when a SQL statement runs. You can
monitor the statistics for a SQL statement execution using the V$SQL_MONITOR and
V$SQL_PLAN_MONITOR views.
Execution plan output is a representation of a tree of row sources. In such a tree format,
the leaf at the left on each level of the tree is where the execution starts. You interpret an
execution plan and a tree in much the same manner.
An execution plan alone cannot tell you whether a plan is good or not; you may need to
perform additional testing and tuning.
Table of Contents
| Top of page |
| Learning Objectives |
| 1.Performing SQL monitoring |
| 2.Interpreting an execution plan |
| 3.Reading complex execution plans |
| Summary |
Copyright 2009 SkillSoft. All rights reserved.
SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries.
All other logos or trademarks are the property of their respective owners.
Exercise overview
In the EP schema, the TEST table consists of two columns - C and D. All rows of column
C contain the value 1 and all rows of column D contain a string of the letter A. An index
has been created on the C column. Using the TEST table, you want to examine various
methods that can be used to extract the execution plan used by the optimizer to execute
a query.
In this exercise, you're required to extract execution plans used by the optimizer.
This involves the following tasks:
Steps list
Instructions
1. Type @ep_monitor and press Enter
2. Type / and press Enter
3. Type / and press Enter
4. Type / and press Enter
5. Click Minimize
Steps list
Instructions
1. Type / and press Enter
2. Type / and press Enter
3. Type / and press Enter
4. Click the Minimize icon
Steps list
Instructions
1. Type @ep_execute_with_all and press Enter
2. Type @ep_retrieve_all_plans and press Enter
3. Type @ep_retrieve_awr and press Enter
4. Type EXEC DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT('ALL'); and press Enter
5. Type @ep_show_awr and press Enter
Table of Contents
| Top of page |
| Learning Objective |
| Exercise overview |
| Task 1: Extracting execution plans |
| Task 2: Monitoring execution plans |
| Task 3: Retrieving execution plans |
Graphic
The Star Schema Model contains a fact table named SALES, surrounded by four
Dimension/Lookup tables on each corner PRODUCTS, CUSTOMERS, TIMES,
and CHANNELS. Each of the Dimension/Lookup table is connected to the fact
table.
A star query is a join between a fact table and a number of dimension tables. Each
dimension table is joined to the fact table using a primary key to foreign key join. But the
dimension tables are not joined to each other.
The Cost-Based Optimizer or CBO recognizes star queries and generates efficient
execution plans for them. A typical fact table contains keys and measures.
For example, in the Sales History schema, the SALES fact table contains the
Graphic
The PRODUCTS table contains the PROD_ID, PROD_NAME, and PROD_DESC
fields. The CUSTOMERS table contains the CUST_ID, CUST_GENDER, and
CUST_CITY fields. The TIMES table contains the TIME_ID, DAY_NAME, and
CALENDAR_YEAR fields. And the CHANNELS table contains the CHANNEL_ID,
CHANNEL_DESC, and CHANNEL_CLASS fields.
Note
It is easy to generalize this model to include more than one fact table.
The snowflake schema is a more complex data warehouse model than a star schema,
and is a type of star schema. It is called a snowflake schema because the diagram of the
schema resembles a snowflake. Snowflake schemas normalize dimensions to eliminate
redundancy. That is, the dimension data has been grouped into multiple tables instead of
one large table.
For example, a product dimension table in a star schema might be normalized into a
PRODUCTS table, a PRODUCT_CATEGORY table, and a PRODUCT_MANUFACTURER table in
a snowflake schema or you can normalize the CUSTOMERS table using the COUNTRIES
table.
While this saves space, it increases the number of dimension tables and requires more
foreign key joins. The result is more complex queries and reduced query performance.
Graphic
The Snowflake Schema Model contains the SALES table in the center. This table
is connected to the PRODUCTS, CUSTOMERS, COUNTRIES, TIMES, and
CHANNELS tables.
Note
It is suggested that you select a star schema over a snowflake schema unless you
have a clear reason not to.
Consider this star query example.
Code
SELECT ch.channel_class, c.cust_city,
t.calendar_quarter_desc,
SUM(s.amount_sold) sales_amount
FROM sales s,times t,customers c,channels ch
WHERE s.time_id = t.time_id AND
s.cust_id = c.cust_id AND
s.channel_id = ch.channel_id AND
c.cust_state_province = 'CA' AND
ch.channel_desc IN ('Internet','Catalog') AND
t.calendar_quarter_desc IN ('1999-Q1','1999-Q2')
GROUP BY ch.channel_class, c.cust_city,
t.calendar_quarter_desc;
In the example star query, for the star transformation to operate, it is supposed that the
SALES table of the Sales History schema has bitmap indexes on the TIME_ID,
CHANNEL_ID, and CUST_ID columns.
Code
SELECT ch.channel_class, c.cust_city,
t.calendar_quarter_desc,
SUM(s.amount_sold) sales_amount
FROM sales s,times t,customers c,channels ch
WHERE s.time_id = t.time_id AND
s.cust_id = c.cust_id AND
s.channel_id = ch.channel_id AND
c.cust_state_province = 'CA' AND
ch.channel_desc IN ('Internet','Catalog') AND
t.calendar_quarter_desc IN ('1999-Q1','1999-Q2')
GROUP BY ch.channel_class, c.cust_city,
t.calendar_quarter_desc;
Before you identify the benefits of a star transformation, you should review how a join on
a star schema is processed without their benefits.
Graphic
The Execution Plan Without Star Transformation image contains a flowchart, and
the result of running the query. The flowchart begins with a Hash Join that
connects with the CHANNELS table and another Hash Join. The second Hash
Join connects to the TIMES table and a third Hash Join. The third Hash Join in
turn connects with the CUSTOMERS and the SALES tables.
The fundamental issue with this plan, which is executed without star transformation, is
that the query always starts joining the SALES table to a dimension table. This results in a
very large number of rows that can only be trimmed down by the other parent joins in the
execution plan.
To get the best possible performance for star queries, it is important to follow some basic
guidelines or conditions:
A bitmap index should be built on each of the foreign key columns of the fact table or tables.
The STAR_TRANSFORMATION_ENABLED initialization parameter should be set to TRUE. This
enables an important optimizer feature for star queries. It is set to FALSE by default for backwards
compatibility.
When a data warehouse satisfies these conditions, the majority of the star queries that
run in the data warehouse use the query execution strategy known as star transformation.
Star transformation provides very efficient query performance for star queries.
Star transformation is a powerful optimization technique that relies on implicitly rewriting
(or transforming) the SQL of the original star query. The end user never needs to know
any of the details about the star transformation. The system's CBO automatically selects
star transformation where appropriate.
Oracle processes a star query using two basic phases:
1. The first phase retrieves exactly the necessary rows from the fact table (the result set). Because
this retrieval utilizes bitmap indexes, it is very efficient.
2. The second phase joins this result set to the dimension tables. This operation is called a semijoin.
Note
At least three tables are used in the query (two dimensions and one fact).
Star transformation is not supported for tables with certain characteristics. These
characteristics are
queries with a table hint that is incompatible with a bitmap access path
tables with too few bitmap indexes, because there must be a bitmap index on a fact table column
for the optimizer to generate a subquery for it
remote fact tables, however, remote dimension tables are allowed in the subqueries that are
generated
antijoined tables
tables that are really unmerged views, which are not view partitions
Question
What characteristics cause star transformation to be unsupported for a table?
Options:
1.
2.
3.
4.
Answer
Option 1: Incorrect. There must be a bitmap index on a fact table column for the
optimizer to generate a subquery for it.
Option 2: Correct. Tables that contain queries that refer to antijoined tables,
unmerged nonpartitioned views, and bind variables are not transformed.
Option 3: Correct. Tables that contain queries that refer to remote fact tables are
not transformed. However, remote dimension tables are allowed in the subqueries
that are generated.
Option 4: Incorrect. Tables that contain bind variables are not transformed. This is
also the case for queries with a table hint that is incompatible with a bitmap
access path.
Correct answer(s):
2. Queries containing antijoined tables
3. Queries referring to remote fact tables
Code
SELECT s.amount_sold
FROM sales s
WHERE time_id IN (SELECT time_id
FROM times
WHERE calendar_quarter_desc
IN('1999-Q1','1999-Q2'))
AND
Note
The SQL statement is a theoretical statement that represents what goes on in
phase I.
You can retrieve fact table rows using only one dimension table. Based on the
corresponding dimension filter predicates, like in t.calendar_quarter_desc IN
('1999- Q1','1999-Q2'), from the star query example, the system scans the
dimension table. And for each corresponding row, it probes the corresponding fact bitmap
index and fetches the corresponding bitmap.
Graphic
The image depicts Retrieving fact Rows from One Dimension, which is part of
Phase 1. This phase begins with BITMAP MERGE that connects to BITMAP KEY
ITERATION. BITMAP KEY ITERATION further connects to Dimension Table
Access and Fact Table Bitmap Access. This entire process produces one bitmap.
BITMAP KEY ITERATION then makes each key coming from its left input a lookup key for
the index on its right input, and returns all bitmaps fetched by that index. Note that its left
input supplies join keys from the dimension table in this case.
The last step in this tree merges all fetched bitmaps from the previous steps. This merge
operation produces one bitmap that can be described as representing the rows of the fact
table that join with the rows of interest from the dimension table.
Note
BITMAP_MERGE_AREA_SIZE plays an important role in tuning the performance of
this operation when using the shared server mode. The system does not
recommend using the BITMAP_MERGE_AREA_SIZE parameter unless the
instance is configured with the shared server option. The system recommends
that you enable automatic sizing of SQL working areas by setting
PGA_AGGREGATE_TARGET instead. BITMAP_MERGE_AREA_SIZE is retained for
backward compatibility.
You can also retrieve fact rows from all dimensions in the first phase. When you do this,
the steps for retrieving fact rows from one dimension are repeated for each dimension
table. So each BITMAP MERGE in the plan generates a bitmap for a single dimension
table. To identify all rows from the fact table that are of interest, the system must intersect
all generated bitmaps.
This is to eliminate fact rows that join with one dimension, but not with all of them. This is
achieved by performing a very efficient BITMAP AND operation on all the bitmaps
generated for each dimension. The resulting bitmap can be described as representing the
rows from the fact table that are known to join with all the qualified dimension rows.
Graphic
When retrieving fact rows from all dimensions, the process begins with BITMAP
Conversion To Rowids, which is an Intermediate Result Set, or IRS. This connects
to BITMAP AND, which is further connected to Merge 1, Merge i, and Merge n,
which are separated by ellipses. This whole procedure ANDs multiple bitmaps
together.
Note
Until now, only fact bitmap indexes and dimension tables were used. To further
access the fact table, the system must convert the generated bitmap to a rowids
set.
After the result set is determined, the system enters phase 2 of the star transformation
algorithm. In this phase, it is needed to join the sales data, corresponding to the result
set, with the dimension tables data used to group the rows pertaining to the query's select
list.
Note that a hash join is performed between the fact table and its dimensions. Although a
hash join is statistically the most-used technique to join rows in a star query, this might
not be always true, as this is evaluated by the CBO.
Graphic
Joining the Intermediate Result Set with Dimensions is part of Phase 2. This
procedure begins with a HASH JOIN that connects to Dimension n Table Access
and a HASH JOIN in a dotted circle. The dotted HASH JOIN connects to a
Dimension i Table Access in a dotted circle and another HASH JOIN. This HASH
JOIN further connects to Dimension 1 Table Access and Fact Table Access From
IRS.
This query is a possible plan to answer the query in the star query example of execution
plan without star transformation. Note that for formatting purposes, only the channels and
times dimensions are shown. It is easy to generalize the case for n dimensions.
Code
SORT GROUP BY
HASH JOIN
HASH JOIN
TABLE ACCESS BY INDEX ROWID SALES
BITMAP CONVERSION TO ROWIDS
BITMAP AND
BITMAP MERGE
BITMAP KEY ITERATION
BUFFER SORT
TABLE ACCESS FULL CHANNELS
BITMAP INDEX RANGE SCAN SALES_CHANNELS_BX
BITMAP MERGE
BITMAP KEY ITERATION
BUFFER SORT
TABLE ACCESS FULL TIMES
BITMAP INDEX RANGE SCAN SALES_TIMES_BX
'...
Note
It is supposed that SALES is not partitioned.
In the previous execution plan, you notice that each dimension table is accessed twice
once during the first phase, where the system determines the necessary fact table rows.
And once when joining the fact rows to each dimension table during the second phase.
This might be a performance issue if the dimension tables are big and there is no fast
access path to them for solving the problem.
In such cases, the system might decide to create temporary tables containing information
needed for both phases. This decision is made if the costs for creating a temporary table,
consisting of the result set for both the predicate and the join columns on the dimension
table, is cheaper than accessing the dimension table twice. In the previous execution plan
example, the TIMES and CHANNELS tables are very small, and accessing them using a
full table scan is not a big deal.
Code
SORT GROUP BY
HASH JOIN
HASH JOIN
TABLE ACCESS BY INDEX ROWID SALES
BITMAP CONVERSION TO ROWIDS
BITMAP AND
BITMAP MERGE
BITMAP KEY ITERATION
BUFFER SORT
TABLE ACCESS FULL CHANNELS
BITMAP INDEX RANGE SCAN SALES_CHANNELS_BX
BITMAP MERGE
BITMAP KEY ITERATION
BUFFER SORT
TABLE ACCESS FULL TIMES
BITMAP INDEX RANGE SCAN SALES_TIMES_BX
'...
TABLE ACCESS FULL CHANNELS
TABLE ACCESS FULL TIMES
The creation of these temporary tables and the data insertion are shown in this execution
plan.
The plan contains an extract from a plan using temporary tables for the CUSTOMERS
table. The name of those temporary tables is system-generated and varies.
Code
LOAD AS SELECT
SYS_TEMP_0FD9D6720_BEBDC
TABLE ACCESS FULL
CUSTOMERS
'...
filter("C"."CUST_STATE_PROVINCE"='CA')
In addition, temporary tables are not used by star transformation under two conditions:
Code
CREATE BITMAP INDEX sales_q_bjx
ON sales(times.calendar_quarter_desc)
FROM sales, times
WHERE sales.time_id = times.time_id
The processing of the same star query using the bitmap join index is similar to the
previous example. The only difference is that the system uses the join index instead of a
single-table bitmap index to access the times data in the first phase of the star query.
The difference between this plan as compared to the previous one is that the inner part of
the bitmap index scan for the times dimension has no subselect in the rewritten query for
phase 1. This is because the join predicate information on
TIMES.CALENDAR_QUARTER_DESC can be satisfied with the SALES_Q_BJX bitmap join
index.
Note that access to the join index is done twice because the corresponding query's
predicate is t.calendar_quarter_desc IN ('1999-Q1','1999-Q2').
Code
SORT GROUP BY
HASH JOIN
HASH JOIN
TABLE ACCESS BY INDEX ROWID SALES
BITMAP CONVERSION TO ROWIDS
BITMAP AND
BITMAP MERGE
BITMAP KEY ITERATION
BUFFER SORT
TABLE ACCESS FULL CHANNELS
BITMAP INDEX RANGE SCAN SALES_CHANNELS_BX
BITMAP OR
BITMAP INDEX SINGLE VALUE SALES_Q_BJX
BITMAP INDEX SINGLE VALUE SALES_Q_BJX
TABLE ACCESS FULL CHANNELS
TABLE ACCESS FULL TIMES
The types of hints available for a star transformation are
STAR_TRANSFORMATION
The STAR_TRANSFORMATION hint makes the optimizer use the best plan in which the
transformation has been used. Without the hint, the optimizer could make a cost-based
decision to use the best plan generated without the transformation, instead of the best plan
for the transformed query.
Even if the hint is given, there is no guarantee that the transformation takes place. The
optimizer only generates the subqueries if it seems reasonable to do so. If no subqueries
are generated, there is no transformed query, and the best plan for the untransformed
query is used, regardless of the hint.
FACT, and
The FACT hint is used in the context of the star transformation to indicate to the
transformation that the hinted table should be considered as a fact table and all other
tables regardless of their size are considered as dimensions.
The FACT hint might be useful only in case there are more than one fact tables accessed
in the star query.
NO_FACT
The NO_FACT hint is used in the context of the star transformation to indicate to the
transformation that the hinted table should not be considered as a fact table.
The NO_FACT hint might be useful only in case there are more than one fact tables
accessed in the star query.
Question
Identify the statements that accurately describe star transformation hints.
Options:
1.
The FACT hint indicates that the hinted table should be considered as a fact table
2.
The NO_FACT hint indicates that the hinted table should not be considered as a fact
table
3.
The STAR_TRANSFORMATION hint might only be useful when there are multiple fact
tables accessed in a star query
4.
The use of the STAR_TRANSFORMATION hint forces the transformation to take place
Answer
Option 1: Correct. The FACT hint is used in the context of the star transformation
to indicate to the transformation that the hinted table should be considered as a
fact table and all other tables regardless of their size are considered as
dimensions.
Option 2: Correct. The NO_FACT hint is used in the context of the star
transformation to indicate to the transformation that the hinted table should not be
considered as a fact table.
Option 3: Incorrect. The FACT and NO_FACT hints might be useful only in case
there are more than one fact table accessed in the star query.
Option 4: Incorrect. The STAR_TRANSFORMATION hint makes the optimizer use
the best plan in which the transformation has been used. Even if the hint is given,
there is no guarantee that the transformation takes place. The optimizer only
generates the subqueries if it seems reasonable to do so.
Correct answer(s):
1. The FACT hint indicates that the hinted table should be considered as a fact
table
2. The NO_FACT hint indicates that the hinted table should not be considered as a
fact table
In the four examples of the bitmap join indexes, F represents the fact table, D the
dimension table, PK a primary key, and FK a foreign key. The examples include
Bitmap Join Indexes: Join Model 1
A bitmap join index can be used in the SELECT statement in the first join model to avoid
the join operation. Similar to the materialized join view, a bitmap join index precomputes
the join and stores it as a database object. The difference is that a materialized join view
materializes the join into a table while a bitmap join index materializes the join into a
bitmap index.
C1 is the indexed column in the dimension table.
In the first join model of bitmap join indexes, the dimension table contains one index
column, c1 and a primary key column, pk. This is connected to the fact table that contains
only a foreign key column, fk.
The query using the bitmap join index is the following:
CREATE BITMAP INDEX bji ON f(d.c1)
FROM f, d
WHERE d.pk = f.fk;
And the select query is the following:
SELECT sum(f.facts)
FROM d, f
WHERE d.pk = f.fk AND d.c1 = 1;
Bitmap Join Indexes: Join Model 2
The second model is an extension of model 1, requiring a concatenated bitmap join index
to represent it.
Note that BJX, in this case, can also be used to answer the second select statement
without the portion after the second AND. This is due to the fact that D.C1 is the leading
part of the BJX.
In the second join model of bitmap join indexes, the dimension table contains two index
columns, c1 and c2, and a primary key column, pk. This table is connected to the fact
table that contains a foreign key column, fk.
The query using the concatenated bitmap join index is the following:
CREATE BITMAP INDEX bjx ON f(d.c1,d.c2)
FROM f, d
WHERE d.pk = f.fk;
And the select query is the following:
SELECT sum(f.facts)
FROM d, f
WHERE d.pk = f.fk AND d.c1 = 1 AND d.c2 = 1;
Bitmap Join Indexes: Join Model 3, and
The third model also requires the concatenated bitmap join index. In this case, two
dimension tables are used.
In the third join model of bitmap join indexes, there are two dimension tables d1 and d2,
and a fact table. d1 contains one index column, c1. Both d1 and d2 a primary key column,
pk each. The fact table contains two foreign key columns, fk1 and fk2. d1 is connected to
the fact table, which in turn is connected to d2. d1 and d2 are not directly connected to
each other.
The query using the concatenated bitmap join index is the following:
CREATE BITMAP INDEX bjx ON f(d1.c1,d2.c1)
FROM f, d1, d2
WHERE d1.pk = f.fk1 AND d2.pk = f.fk2;
And the select query is the following:
SELECT sum(f.sales)
FROM d1, f, d2
WHERE d1.pk = f.fk1 AND d2.pk = f.fk2 AND
d1.c1 = 1 AND d2.c1 = 2;
Bitmap Join Indexes: Join Model 4
The snowflake model, which is the fourth model, involves joins between two or more
dimension tables. It can be expressed by a bitmap join index.
The bitmap join index can be either single or concatenated depending on the number of
columns in the dimension tables to be indexed.
A bitmap join index on D1.C1 with a join between D1 and D2 and a join between D2 and F
can be created with BJX.
In the fourth join model of bitmap join indexes, there are two dimension tables, d1 and d2,
and a fact table. d1 and d2 both contain an index column, c1 and c2, and a primary key
column, pk. The fact table contains only a foreign key column fk. d1 and d2 are connected
to each other. And d2 is connected to the fact table.
The query using the concatenated bitmap join index is the following:
CREATE BITMAP INDEX bjx ON f(d1.c1)
FROM f, d1, d2
WHERE d1.pk = d2.c2 AND d2.pk = f.fk;
And the select query is the following:
SELECT sum(f.sales)
FROM d1, d2, f
WHERE d1.pk = d2.c2 AND d2.pk = f.fk AND
d1.c1 = 1;
Summary
You can use a simple star schema to connect a large fact table with smaller dimension or
lookup tables. Queries from these tables, called star queries, often join the fact and one
or more dimension tables using primary and foreign keys.
Although you can execute queries without a star transformation, doing so results in a
large number of rows. To use the star transformation execution strategy, foreign keys of
fact or other tables should have a bitmap index. The STAR_TRANSFORMATION_ENABLED
initialization parameter should be set to TRUE.
The first phase of star transformation execution uses bitmap indexes to retrieve result
sets, and the second phase joins result sets to dimension tables. To avoid performance
issues caused by large dimension tables, use temporary tables that contain information
for both phases.
Table of Contents
| Top of page |
| Learning Objective |
| 1.Star schema and star transformation |
| 2.Queries in star transformation |
| Summary |
Copyright 2009 SkillSoft. All rights reserved.
SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries.
All other logos or trademarks are the property of their respective owners.
use star transformation and access the benefits of using this optimizer technique
Exercise overview
You have written a query that queries the CUSTOMERS, SALES, TIMES, and
CHANNELS tables and returns the CHANNEL_CLASS, CUST_CITY, CALENDAR, and
SALES_AMOUNT columns based on a number of WHERE conditions and joins. You
have saved the query to a script called "sales query." You want to optimize the query to
use star transformation and make further use of the benefits of this technique.
In this exercise, you're required to optimize a query to use star transformation.
This involves the following tasks:
enhancing optimization
querying PLAN_TABLE
Steps list
Instructions
1. Type ALTER SYSTEM FLUSH BUFFER_CACHE; and press Enter
2. Type ALTER SYSTEM FLUSH SHARED_POOL; and press Enter
3. Type @sales_query and press Enter
your session. Do not use a temporary table for the star transformation. Then execute the
"sales_query" script using the @ command. Type each command using one line only.
Steps list
Instructions
1. Type ALTER SESSION SET star_transformation_enabled = temp_disable; and press Enter
2. Type @sales_query and press Enter
Steps list
Instructions
1. Type ALTER SESSION SET star_transformation_enabled = true; and press Enter
2. Type @sales_query and press Enter
Steps list
Instructions
1. Type ALTER TABLE customers ENABLE CONSTRAINT customers_pk; and press Enter
2. Type @create_bji and press Enter
dynamically determine which SALES partitions to access for your "sales_query" query.
You have already flushed the buffer cache and shared pool. Execute the "sales_query"
and "dynamic_partition_pruning" scripts respectively using the @ command. Then view
the OTHER column of PLAN_TABLE table for the PARTITION RANGE operation. Type
each command using one line only.
Steps list
Instructions
1. Type @sales_query and press Enter
2. Type @dynamic_partition_pruning and press Enter
3. Type SELECT other FROM plan_table WHERE operation = 'PARTITION RANGE'; and press Enter
Table of Contents
| Top of page |
| Learning Objective |
| Exercise overview |
| Task 1: Viewing optimizer results |
| Task 2: Using star transformation |
| Task 3: Enhancing optimization |
| Task 4: Eliminating table access |
| Task 5: Querying PLAN_TABLE |
Copyright 2009 SkillSoft. All rights reserved.
SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries.
All other logos or trademarks are the property of their respective owners.