Tuesday, August 27, 2013

Find all available Execution Plans for a specific SQL statement


When you have a specific SQL statement that is been running in your database (e.g., it might be part of nightly ETL flow that is used for loading your Data Warehouse), then how can you get a list of all available execution plans that the optimizer has chosen for this specific statement?

Each statement is uniquely identified by an SQL_ID and whenever the statement undergoes a hard parsing, then an execution plan is generated, which is identified uniquely by a hash value, called plan_hash_value.
Ideally, for a specific statement the same execution plan must be generated each time is being hard parsed. However in practice, there might be more than one execution plans, each one with a different cost and resulting in different execution times. The generation of a different execution plan might be due to a number of reasons, such as object statistics, optimizer environment (e.g., init parameters relevant to the optimizer), or the version of the Oracle software.

Lets see an example:

Assume the following SQL statement:
------------------------------------------------------------------------------------------------------------

nikos@NIKOSDB> get mysql
  1  SELECT ch.channel_class, c.cust_city, t.calendar_quarter_desc,
  2     SUM(s.amount_sold) sales_amount
  3  FROM sales s, times t, customers c, channels ch
  4  WHERE s.time_id = t.time_id
  5  AND   s.cust_id = c.cust_id
  6  AND   s.channel_id = ch.channel_id
  7  AND   c.cust_state_province = 'CA'
  8  AND   ch.channel_desc in ('Internet','Catalog')
  9  AND   t.calendar_quarter_desc IN ('1999-01','1999-02')
 10* GROUP BY ch.channel_class, c.cust_city, t.calendar_quarter_desc
nikos@NIKOSDB> /

CHANNEL_CLASS        CUST_CITY                      CALENDA SALES_AMOUNT
-------------------- ------------------------------ ------- ------------
Indirect             Quartzhill                     1999-01        987.3
Indirect             Arbuckle                       1999-02        241.2
Indirect             Legrand                        1999-02        18.66
Indirect             Los Angeles                    1999-01      1886.19
Indirect             Cloverdale                     1999-02       266.28
Indirect             Pescadero                      1999-02       298.44
Indirect             Legrand                        1999-01        26.32
Indirect             Pescadero                      1999-01        26.32
Indirect             San Mateo                      1999-01      8754.59
Indirect             Arbuckle                       1999-01       270.08
Indirect             Montara                        1999-01       289.07
Indirect             Los Angeles                    1999-02      2128.59
Indirect             Pala                           1999-02       936.62
Indirect             El Sobrante                    1999-02      3744.03
Indirect             El Sobrante                    1999-01      5392.34
Indirect             Cloverdale                     1999-01        52.64
Indirect             San Francisco                  1999-02        11257
Indirect             San Francisco                  1999-01      3058.27
Indirect             Pala                           1999-01      3263.93
Indirect             San Mateo                      1999-02     21399.42
Indirect             Montara                        1999-02      1618.01
Indirect             Quartzhill                     1999-02       412.83

22 rows selected.

Elapsed: 00:00:00.26
------------------------------------------------------------------------------------------------------------
Lets find the SQL_ID:
------------------------------------------------------------------------------------------------------------

nikos@NIKOSDB> @fs
Enter value for sql_text: %SELECT ch.channel_class, c.cust_city, t.calendar_quarter_desc%
Enter value for sql_id:

     PARSING_SCHEMA_NAME       SQL_ID         CHILD  PLAN_HASH      EXECS     AVG_ETIME      AVG_LIO SQL_TEXT
------------------------------ ------------- ------ ---------- ---------- ------------- ------------ ------------------------------------------------------------
SH                             9j820km30uynd      0 1062259086          1           .97       19,317 SELECT ch.channel_class, c.cust_city, t.calendar_quarter_des
                                                                                                     c,    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 ('I
                                                                                                     nternet','Catalog') AND   t.calendar_quarter_desc IN ('1999-
                                                                                                     01','1999-02') GROUP BY ch.channel_class, c.cust_city, t.cal
                                                                                                     endar_quarter_desc

SH                             9j820km30uynd      1 2000181989          1           .19        2,641 SELECT ch.channel_class, c.cust_city, t.calendar_quarter_des
                                                                                                     c,    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 ('I
                                                                                                     nternet','Catalog') AND   t.calendar_quarter_desc IN ('1999-
                                                                                                     01','1999-02') GROUP BY ch.channel_class, c.cust_city, t.cal
                                                                                                     endar_quarter_desc


Elapsed: 00:00:00.09
------------------------------------------------------------------------------------------------------------
As you can see there are two child cursors (CHILD: 0 and 1) for the same SQL statement with SQL_ID: '9j820km30uynd'. In a previous post we discussed about child cursors. What they are and why are created. So we have found the SQL_ID. Here is the script that we used for this task:

------------------------------------------------------------------------------------------------------------

nikos@NIKOSDB> host cat fs.sql
col sql_text for a60 wrap
set verify off
set pagesize 999
set lines 999
col username format a13
col prog format a22
col sid format 999
col child_number format 99999 heading CHILD
col ocategory format a10
col avg_etime format 9,999,999.99
col avg_pio format 9,999,999.99
col avg_lio format 999,999,999
col etime format 9,999,999.99

select PARSING_SCHEMA_NAME, sql_id, child_number, plan_hash_value plan_hash, executions execs,
(elapsed_time/1000000)/decode(nvl(executions,0),0,1,executions) avg_etime,
buffer_gets/decode(nvl(executions,0),0,1,executions) avg_lio,
sql_text
from gv$sql s
where upper(sql_text) like upper(nvl('&sql_text',sql_text))
and sql_text not like '%from gv$sql where upper(sql_text) like nvl(%'
and sql_id like nvl('&sql_id',sql_id)
order by 1, 2, 3
/
------------------------------------------------------------------------------------------------------------
Now that we know the SQL_ID it is easy to find the available execution plans, along with the corresponding elapsed time and cost. There are basically two sources for the execution plans. An execution plan might reside in the Library Cache of the Shared Pool (so we query one of the V$SQL... views), and/or in the AWR repository (so we query a DBA_HIST... view):

------------------------------------------------------------------------------------------------------------

nikos@NIKOSDB> @fs_plans

********************************************************
Find the available execution plans for a specific SQL_ID
********************************************************


Session altered.

Elapsed: 00:00:00.00
Enter value for sql_id: 9j820km30uynd

SOURCE                  INST_ID SQL_ID        PLAN_HASH_VALUE AVG_ET_SECS     AVG_PX        COST      TIMESTAMP         PARSING_SCHEMA_NAME
-------------------- ---------- ------------- --------------- ----------- ---------- ----------- ------------------------- ----------------
dba_hist_sql_plan               9j820km30uynd      1858418313         .03          0        1113 22-08-2013 21:46:21
dba_hist_sql_plan               9j820km30uynd      2093608901         .05          0         558 22-08-2013 21:45:53
dba_hist_sql_plan               9j820km30uynd      2000181989         .05          0         929 22-08-2013 21:46:11
dba_hist_sql_plan               9j820km30uynd      3208336303         .09          0         558 22-08-2013 22:09:03
dba_hist_sql_plan               9j820km30uynd       127002096         .14          0         558 22-08-2013 22:28:46
gv$sqlarea_plan_hash          1 9j820km30uynd      2000181989         .19          0         929 27-08-2013 16:55:17       SH
dba_hist_sql_plan               9j820km30uynd      1062259086         .97          0         558 27-08-2013 10:17:37
gv$sqlarea_plan_hash          1 9j820km30uynd      1062259086         .97          0         558 27-08-2013 10:17:37       SH
dba_hist_sql_plan               9j820km30uynd       632852794        1.05          0         558 25-08-2013 20:47:17
dba_hist_sql_plan               9j820km30uynd      3018881530        1.14          0         558 26-08-2013 18:15:31

10 rows selected.

Elapsed: 00:00:00.07
------------------------------------------------------------------------------------------------------------
As you can see there are more than one available execution plans for the SQL_ID '9j820km30uynd' both in the library cache and the AWR repository (see the "source" column). This is obvious by the different plan_hash_values. Also note that the plans have different elapsed times and cost. The timestamp denotes the time that the specific plan was generated.

The script that we have used is the following:
------------------------------------------------------------------------------------------------------------

nikos@NIKOSDB> host cat fs_plans.sql
---------------------------------------------------------------------------------------------
--                              Find the available execution plans for a specific SQL_ID
--
--              Note that the AVG_ET_SECS (average elpased time) will not be accurate for parallel queries.
--                              The ELAPSED_TIME column contains the sum of all parallel slaves. So the
--              script divides the value by the number of PX slaves used which gives an
--              approximation.
--
--              Note also that if parallel slaves are spread across multiple nodes on
--              a RAC database the PX_SERVERS_EXECUTIONS column will not be set.
--
--                              author: oradwstories.blogspot.com
---------------------------------------------------------------------------------------------

prompt
prompt ********************************************************
prompt Find the available execution plans for a specific SQL_ID
prompt ********************************************************
prompt

set linesize 999
col avg_et_secs justify right format 9999999.99
col cost justify right format 9999999999
col timestamp justify center format a25
col parsing_schema_name justify center format a30
col inst_id format 999999999

alter session set nls_date_format='dd-mm-yyyy hh24:mi:ss';

select  'gv$sqlarea_plan_hash' source, INST_ID, SQL_ID, PLAN_HASH_VALUE,
                round(elapsed_time/decode(nvl(executions,0),0,1,executions)/1e6/
                decode(px_servers_executions,0,1,px_servers_executions)/decode(nvl(executions,0),0,1,executions),2)     avg_et_secs,
                px_servers_executions/decode(nvl(executions,0),0,1,executions) avg_px,
                optimizer_cost cost, LAST_LOAD_TIME timestamp, parsing_schema_name --FIRST_LOAD_TIME, LAST_LOAD_TIME, LAST_ACTIVE_TIME, SQL_PROFILE
from gv$sqlarea_plan_hash
where sql_id = nvl(trim('&&sql_id'),sql_id)
UNION
SELECT 'dba_hist_sql_plan' source, null INST_ID, t1.sql_id sql_id, t1.plan_hash_value plan_hash_value, t2.avg_et_secs avg_et_secs, t2.avg_px, t1.cost cost, t1.timestamp timestamp, NULL parsing_schema_name
FROM dba_hist_sql_plan t1,
        (
                SELECT sql_id, plan_hash_value, --round(SUM(elapsed_time_total)/decode(SUM(executions_total),0,1,SUM(executions_total))/1e6,2) avg_et_secs
                round(SUM(elapsed_time_total)/decode(SUM(executions_total),0,1,SUM(executions_total))/1e6/
                decode(SUM(px_servers_execs_total),0,1,SUM(px_servers_execs_total))/decode(SUM(executions_total),0,1,SUM(executions_total)),2)  avg_et_secs,
                SUM(px_servers_execs_total)/decode(SUM(executions_total),0,1,SUM(executions_total)) avg_px
                FROM dba_hist_sqlstat
                WHERE
                        executions_total > 0
                GROUP BY        sql_id, plan_hash_value
        ) t2
WHERE
        t1.sql_id = nvl(TRIM('&sql_id.'), t1.sql_id)
        AND t1.depth = 0
        AND t1.sql_id = t2.sql_id(+)
        AND t1.plan_hash_value = t2.plan_hash_value(+)
order by avg_et_secs, cost
/
undef sql_id
------------------------------------------------------------------------------------------------------------
If we want to inspect one of these plans, it is very easy using the corresponding DBMS_XPLAN.DISPLAY procedure. For example,  we can see that there are available two different execution plans loaded in the library cache (source: gv$sqlarea_plan_hash). So we can use the procedure DBMS_XPLAN.DISPLAY_CURSOR, as follows:

------------------------------------------------------------------------------------------------------------

nikos@NIKOSDB> host cat xplan.sql
set linesize 999
set pagesize 999

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

nikos@NIKOSDB> @xplan
Enter value for sql_id: 9j820km30uynd
Enter value for child_number:

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  9j820km30uynd, child number 0
-------------------------------------
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-01','1999-02') GROUP BY ch.channel_class, c.cust_city,
t.calendar_quarter_desc

Plan hash value: 1062259086

-----------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                               | Name                      | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | Pstart| Pstop |  OMem |  1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                        |                           |        |       |   558 (100)|          |       |       |       |       |          |
|   1 |  TEMP TABLE TRANSFORMATION              |                           |        |       |         |             |       |       |       |       |          |
|   2 |   LOAD AS SELECT                        |                           |        |       |         |             |       |       |   264K|   264K|  264K (0)|
|*  3 |    TABLE ACCESS FULL                    | CUSTOMERS                 |    383 |  9958 |   406   (1)| 00:00:05 |       |       |       |       |          |
|   4 |   HASH GROUP BY                         |                           |    254 | 18542 |   153   (2)| 00:00:02 |       |       |   744K|   744K| 1154K (0)|
|*  5 |    HASH JOIN                            |                           |    254 | 18542 |   129   (2)| 00:00:02 |       |       |   855K|   855K| 1248K (0)|
|*  6 |     TABLE ACCESS FULL                   | TIMES                     |    183 |  2928 |    18   (0)| 00:00:01 |       |       |       |       |          |
|*  7 |     HASH JOIN                           |                           |    254 | 14478 |   110   (1)| 00:00:02 |       |       |   744K|   744K| 1289K (0)|
|*  8 |      HASH JOIN                          |                           |    254 | 10668 |   107   (0)| 00:00:02 |       |       |   825K|   825K|  376K (0)|
|*  9 |       TABLE ACCESS FULL                 | CHANNELS                  |      2 |    42 |     3   (0)| 00:00:01 |       |       |       |       |          |
|  10 |       PARTITION RANGE SUBQUERY          |                           |    254 |  5334 |   104   (0)| 00:00:02 |KEY(SQ)|KEY(SQ)|       |       |          |
|  11 |        TABLE ACCESS BY LOCAL INDEX ROWID| SALES                     |    254 |  5334 |   104   (0)| 00:00:02 |KEY(SQ)|KEY(SQ)|       |       |          |
|  12 |         BITMAP CONVERSION TO ROWIDS     |                           |        |       |         |             |       |       |       |       |          |
|  13 |          BITMAP AND                     |                           |        |       |         |             |       |       |       |       |          |
|  14 |           BITMAP MERGE                  |                           |        |       |         |             |       |       |  1024K|   512K| 4096  (0)|
|  15 |            BITMAP KEY ITERATION         |                           |        |       |         |             |       |       |       |       |          |
|  16 |             BUFFER SORT                 |                           |        |       |         |             |       |       | 73728 | 73728 |          |
|* 17 |              TABLE ACCESS FULL          | CHANNELS                  |      2 |    26 |     3   (0)| 00:00:01 |       |       |       |       |          |
|* 18 |             BITMAP INDEX RANGE SCAN     | SALES_CHANNEL_BIX         |        |       |         |             |KEY(SQ)|KEY(SQ)|       |       |          |
|  19 |           BITMAP MERGE                  |                           |        |       |         |             |       |       |  1024K|   512K|37888  (0)|
|  20 |            BITMAP KEY ITERATION         |                           |        |       |         |             |       |       |       |       |          |
|  21 |             BUFFER SORT                 |                           |        |       |         |             |       |       | 73728 | 73728 |          |
|* 22 |              TABLE ACCESS FULL          | TIMES                     |    183 |  2928 |    18   (0)| 00:00:01 |       |       |       |       |          |
|* 23 |             BITMAP INDEX RANGE SCAN     | SALES_TIME_BIX            |        |       |         |             |KEY(SQ)|KEY(SQ)|       |       |          |
|  24 |           BITMAP MERGE                  |                           |        |       |         |             |       |       |  1024K|   512K|37888  (0)|
|  25 |            BITMAP KEY ITERATION         |                           |        |       |         |             |       |       |       |       |          |
|  26 |             BUFFER SORT                 |                           |        |       |         |             |       |       |  2992K|   769K|96256  (0)|
|  27 |              TABLE ACCESS FULL          | SYS_TEMP_0FD9D6605_C37A91 |    383 |  1915 |     2   (0)| 00:00:01 |       |       |       |       |          |
|* 28 |             BITMAP INDEX RANGE SCAN     | SALES_CUST_BIX            |        |       |         |             |KEY(SQ)|KEY(SQ)|       |       |          |
|  29 |      TABLE ACCESS FULL                  | SYS_TEMP_0FD9D6605_C37A91 |    383 |  5745 |     2   (0)| 00:00:01 |       |       |       |       |          |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------

SQL_ID  9j820km30uynd, child number 1
-------------------------------------
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-01','1999-02') GROUP BY ch.channel_class, c.cust_city,
t.calendar_quarter_desc

Plan hash value: 2000181989

--------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                              | Name              | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | Pstart| Pstop |  OMem |  1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                       |                   |        |       |   929 (100)|       |          |       |       |       |          |
|   1 |  HASH GROUP BY                         |                   |     16 |  1344 |   929   (1)| 00:00:12 |       |       |   744K|   744K| 1148K (0)|
|*  2 |   HASH JOIN                            |                   |     16 |  1344 |   907   (1)| 00:00:11 |       |       |   783K|   783K| 1244K (0)|
|*  3 |    HASH JOIN                           |                   |     16 |  1088 |   888   (1)| 00:00:11 |       |       |   801K|   801K|  365K (0)|
|*  4 |     HASH JOIN                          |                   |     16 |   752 |   885   (1)| 00:00:11 |       |       |  1169K|  1100K| 1576K (0)|
|   5 |      PARTITION RANGE SUBQUERY          |                   |     38 |   811 |   479   (1)| 00:00:06 |KEY(SQ)|KEY(SQ)|       |       |          |
|   6 |       TABLE ACCESS BY LOCAL INDEX ROWID| SALES             |     38 |   811 |   479   (1)| 00:00:06 |KEY(SQ)|KEY(SQ)|       |       |          |
|   7 |        BITMAP CONVERSION TO ROWIDS     |                   |        |       |            |       |          |       |       |       |          |
|   8 |         BITMAP AND                     |                   |        |       |            |       |          |       |       |       |          |
|   9 |          BITMAP MERGE                  |                   |        |       |            |       |          |       |  1024K|   512K| 4096  (0)|
|  10 |           BITMAP KEY ITERATION         |                   |        |       |            |       |          |       |       |       |          |
|  11 |            BUFFER SORT                 |                   |        |       |            |       |          |       | 73728 | 73728 |          |
|* 12 |             TABLE ACCESS FULL          | CHANNELS          |      2 |    26 |     3   (0)| 00:00:01 |       |       |       |       |          |
|* 13 |            BITMAP INDEX RANGE SCAN     | SALES_CHANNEL_BIX |        |       |            |       |KEY(SQ)|KEY(SQ)|          |       |          |
|  14 |          BITMAP MERGE                  |                   |        |       |            |       |          |       |  1024K|   512K|37888  (0)|
|  15 |           BITMAP KEY ITERATION         |                   |        |       |            |       |          |       |       |       |          |
|  16 |            BUFFER SORT                 |                   |        |       |            |       |          |       | 73728 | 73728 |          |
|* 17 |             TABLE ACCESS FULL          | TIMES             |    183 |  2928 |    18   (0)| 00:00:01 |       |       |       |       |          |
|* 18 |            BITMAP INDEX RANGE SCAN     | SALES_TIME_BIX    |        |       |            |       |KEY(SQ)|KEY(SQ)|          |       |          |
|* 19 |      TABLE ACCESS FULL                 | CUSTOMERS         |    383 |  9958 |   406   (1)| 00:00:05 |       |       |       |       |          |
|* 20 |     TABLE ACCESS FULL                  | CHANNELS          |      2 |    42 |     3   (0)| 00:00:01 |       |       |       |       |          |
|* 21 |    TABLE ACCESS FULL                   | TIMES             |    183 |  2928 |    18   (0)| 00:00:01 |       |       |       |       |          |
--------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------
We have truncated some of the output but we can see the two different execution plans available in the library cache (note the plan_hash_values at the beginning of each execution plan).

In order to view a specific execution plan from the AWR repository, then we have to use procedure DBMS_XPLAN.DISPLAY_AWR. For example, in order to view plan 2093608901 (plan_hash_value), we can do the following:
------------------------------------------------------------------------------------------------------------

nikos@NIKOSDB> host cat xplan_awr.sql
set linesize 999
set pagesize 999

select * from table( dbms_xplan.display_awr('&sql_id', plan_hash_value => '&plan_hash_value', format =>'ALL ALLSTATS LAST'))
/
nikos@NIKOSDB> @xplan_awr
Enter value for sql_id: 9j820km30uynd
Enter value for plan_hash_value: 2093608901

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 9j820km30uynd
--------------------
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-01','1999-02') GROUP BY ch.channel_class, c.cust_city,
t.calendar_quarter_desc

Plan hash value: 2093608901

--------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                               | Name                      | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                        |                           |        |       |   558 (100)|          |       |       |
|   1 |  TEMP TABLE TRANSFORMATION              |                           |        |       |         |             |       |       |
|   2 |   LOAD AS SELECT                        |                           |        |       |         |             |       |       |
|   3 |    TABLE ACCESS FULL                    | CUSTOMERS                 |    383 |  9958 |   406   (1)| 00:00:05 |       |       |
|   4 |   HASH GROUP BY                         |                           |    254 | 18542 |   153   (2)| 00:00:02 |       |       |
|   5 |    HASH JOIN                            |                           |    254 | 18542 |   129   (2)| 00:00:02 |       |       |
|   6 |     TABLE ACCESS FULL                   | TIMES                     |    183 |  2928 |    18   (0)| 00:00:01 |       |       |
|   7 |     HASH JOIN                           |                           |    254 | 14478 |   110   (1)| 00:00:02 |       |       |
|   8 |      HASH JOIN                          |                           |    254 | 10668 |   107   (0)| 00:00:02 |       |       |
|   9 |       TABLE ACCESS FULL                 | CHANNELS                  |      2 |    42 |     3   (0)| 00:00:01 |       |       |
|  10 |       PARTITION RANGE SUBQUERY          |                           |    254 |  5334 |   104   (0)| 00:00:02 |KEY(SQ)|KEY(SQ)|
|  11 |        TABLE ACCESS BY LOCAL INDEX ROWID| SALES                     |    254 |  5334 |   104   (0)| 00:00:02 |KEY(SQ)|KEY(SQ)|
|  12 |         BITMAP CONVERSION TO ROWIDS     |                           |        |       |         |             |       |       |
|  13 |          BITMAP AND                     |                           |        |       |         |             |       |       |
|  14 |           BITMAP MERGE                  |                           |        |       |         |             |       |       |
|  15 |            BITMAP KEY ITERATION         |                           |        |       |         |             |       |       |
|  16 |             BUFFER SORT                 |                           |        |       |         |             |       |       |
|  17 |              TABLE ACCESS FULL          | CHANNELS                  |      2 |    26 |     3   (0)| 00:00:01 |       |       |
|  18 |             BITMAP INDEX RANGE SCAN     | SALES_CHANNEL_BIX         |        |       |         |             |KEY(SQ)|KEY(SQ)|
|  19 |           BITMAP MERGE                  |                           |        |       |         |             |       |       |
|  20 |            BITMAP KEY ITERATION         |                           |        |       |         |             |       |       |
|  21 |             BUFFER SORT                 |                           |        |       |         |             |       |       |
|  22 |              TABLE ACCESS FULL          | TIMES                     |    183 |  2928 |    18   (0)| 00:00:01 |       |       |
|  23 |             BITMAP INDEX RANGE SCAN     | SALES_TIME_BIX            |        |       |         |             |KEY(SQ)|KEY(SQ)|
|  24 |           BITMAP MERGE                  |                           |        |       |         |             |       |       |
|  25 |            BITMAP KEY ITERATION         |                           |        |       |         |             |       |       |
|  26 |             BUFFER SORT                 |                           |        |       |         |             |       |       |
|  27 |              TABLE ACCESS FULL          | SYS_TEMP_0FD9D660C_C06B4A |    383 |  1915 |     2   (0)| 00:00:01 |       |       |
|  28 |             BITMAP INDEX RANGE SCAN     | SALES_CUST_BIX            |        |       |         |             |KEY(SQ)|KEY(SQ)|
|  29 |      TABLE ACCESS FULL                  | SYS_TEMP_0FD9D660C_C06B4A |    383 |  5745 |     2   (0)| 00:00:01 |       |       |
--------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------

We have also truncated part from the output.

In general, it is very useful to be able to find the various execution plans used for a specific SQL statement, especially in the case when a query's performance suddenly deteriorates, due to a change in the execution plan. Then there might be a need to quickly revert to an older execution plan with better execution time. We will discuss how we can fix the execution plan for a specific SQL statement, with the use of SQL Profiles in a future post.

Enjoy!
Oracle Learner.

No comments:

Post a Comment