Skip to Main Content
  • Questions
  • Why producing multiple versions of execution plan for this SQL?

Breadcrumb

Connor and Chris will both be at AI World from October 12 to October 17 , the premier Oracle conference of 2025. If you're in Vegas, please come say Hi or pop into our sessions

Question and Answer

Connor McDonald

Thanks for the question, Quanwen.

Asked: July 03, 2018 - 6:48 am UTC

Last updated: July 12, 2018 - 9:40 am UTC

Version: 11.2.0.4.0

Viewed 1000+ times

You Asked

Hello, AskTOM teams

A few days ago I found a SQL is running and consuming a lot of CPU resource on my Oracle Database Server 11.2.0.4.0 for Linux x86_64. Next I observed some historical ASH data.

At the same time I had also queried the view "v$active_session_history",

set linesize 200
set pagesize 200  

col event for a40

select *
from
( select sql_id
        , event
        , count(*)
  from v$active_session_history
  where sample_time between to_date('2018-06-28 06:00:00','yyyy-mm-dd hh24:mi:ss')
  and to_date('2018-06-28 11:10:00','yyyy-mm-dd hh24:mi:ss')
  group by sql_id
           , event
  order by count(*) desc
           , event
           , sql_id
)
where rownum <= 6
;

SQL_ID                     EVENT                                      COUNT(*)
-------------------------- ---------------------------------------- ----------
bg8pk89nc71x1                                                            97131  <<==
g72nq3v9j149v                                                            43149
70u5bvgsqwpgq                                                            13501
                           log file sync                                 11754
                           db file async I/O submit                       7057
04ugnv5psmjju                                                             5023

6 rows selected.


Afterwards I used SQLT tool to export this SQL_ID ("bg8pk89nc71x1")'s SQLT reports and I observed the "sqlt_s85770_main.html", about on the part "SQL Tuning Advisor" of that html file I also found the "STA Report" and its full content is as follows,

GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name   : sqlt_s85770_mem
Tuning Task Owner  : SYS
Tuning Task ID     : 21376
Workload Type      : Single SQL Statement
Execution Count    : 1
Current Execution  : EXEC_22249
Execution Type     : TUNE SQL
Scope              : COMPREHENSIVE
Time Limit(seconds): 1800
Completion Status  : COMPLETED
Started at         : 06/28/2018 08:55:50
Completed at       : 06/28/2018 08:56:01

-------------------------------------------------------------------------------
Schema Name: SZD_RESOURCE_V2
SQL ID     : bg8pk89nc71x1
SQL Text   : select count(*) from
             (
              select t.title,t.subject_id,t.cre_user_id,t.view_count,t.area_id
             ,t.case_id from sd_res_id_case PARTITION(year_mark4) t
             where 1 = 1
             and t.delete_flag = '0' and t.forbidden_flag = '1'
              and t.is_school_check = '2'
              and t.from_type = 'fromType.1s1k'
              and t.city_id=:1
              and t.subject_id=:2
             order by t.view_count desc
             ) a
             where rownum < 501
Bind Variables :
 1 -  (VARCHAR2(2000)):ff80808141c605e20141d97f2b4900e1
 2 -  (VARCHAR2(128)):subject.0059

-------------------------------------------------------------------------------
FINDINGS SECTION (2 findings)
-------------------------------------------------------------------------------

1- Index Finding (see explain plans section below)
--------------------------------------------------
  The execution plan of this statement can be improved by creating one or more
  indices.

  Recommendation (estimated benefit: 99.71%)
  ------------------------------------------
  - Consider running the Access Advisor to improve the physical schema design
    or creating the recommended index.  If you choose to create the
    recommended index, consider dropping the index
    "SZD_RESOURCE_V2"."IDX1_RES_ID_CITY_ID" because it is a prefix of the
    recommended index.
    create index SZD_RESOURCE_V2.IDX$$_53800001 on
    SZD_RESOURCE_V2.SD_RES_ID_CASE("CITY_ID","SUBJECT_ID","IS_SCHOOL_CHECK","DE
    LETE_FLAG","FORBIDDEN_FLAG","FROM_TYPE");

  Rationale
  ---------
    Creating the recommended indices significantly improves the execution plan
    of this statement. However, it might be preferable to run "Access Advisor"
    using a representative SQL workload as opposed to a single statement. This
    will allow to get comprehensive index recommendations which takes into
    account index maintenance overhead and additional space consumption.

2- Alternative Plan Finding
---------------------------
  Some alternative execution plans for this statement were found by searching
  the system's real-time and historical performance data.

  The following table lists these plans ranked by their average elapsed time.
  See section "ALTERNATIVE PLANS SECTION" for detailed information on each
  plan.

  id plan hash  last seen            elapsed (s)  origin          note
  -- ---------- -------------------- ------------ --------------- ----------------
   1 4041534880  2018-06-23/04:00:29        0.075 Cursor Cache
   2 3664635048  2018-06-27/06:13:36        0.231 Cursor Cache    original plan
   3  293581336  2018-06-28/05:27:00        3.181 Cursor Cache

  Recommendation
  --------------
  - Consider creating a SQL plan baseline for the plan with the best average
    elapsed time.
    execute dbms_sqltune.create_sql_plan_baseline(task_name =>
            'sqlt_s85770_mem', owner_name => 'SYS', plan_hash_value =>
            4041534880);

-------------------------------------------------------------------------------
ADDITIONAL INFORMATION SECTION
-------------------------------------------------------------------------------
- The optimizer could not merge the view at line ID 3 of the execution plan.
  The optimizer cannot merge a view that contains an "ORDER BY" clause unless
  the statement is a "DELETE" or an "UPDATE" and the parent query is the top
  most query in the statement.

-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------

1- Original
-----------
Plan hash value: 3664635048


--------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                              | Name                        | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                       |                             |     1 |       |  3831   (1)| 00:00:46 |       |       |
|   1 |  SORT AGGREGATE                        |                             |     1 |       |            |          |       |       |
|*  2 |   COUNT STOPKEY                        |                             |       |       |            |          |       |       |
|   3 |    VIEW                                |                             |     1 |       |  3831   (1)| 00:00:46 |       |       |
|*  4 |     SORT ORDER BY STOPKEY              |                             |     1 |   201 |  3831   (1)| 00:00:46 |       |       |
|*  5 |      TABLE ACCESS BY GLOBAL INDEX ROWID| SD_RES_ID_CASE              |     1 |   201 |  3830   (1)| 00:00:46 |     4 |     4 |
|*  6 |       INDEX RANGE SCAN                 | ID1_ID_CASE_DF_ISC_SI_VI_TC |  3784 |       |    59   (0)| 00:00:01 |       |       |
--------------------------------------------------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1
   3 - SEL$2 / A@SEL$1
   4 - SEL$2
   5 - SEL$2 / T@SEL$2
   6 - SEL$2 / T@SEL$2

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter(ROWNUM<501)
   4 - filter(ROWNUM<501)
   5 - filter("T"."CITY_ID"=:1 AND "T"."FORBIDDEN_FLAG"=1 AND "T"."FROM_TYPE"='fromType.1s1k')
   6 - access("T"."DELETE_FLAG"=0 AND "T"."IS_SCHOOL_CHECK"=2 AND "T"."SUBJECT_ID"=:2)
       filter(TBL$OR$IDX$PART$NUM(<?>,0,1,0,ROWID)=4)

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - (#keys=0) COUNT(*)[22]
   4 - (#keys=1) INTERNAL_FUNCTION("T"."VIEW_COUNT")[22]
   5 - "T"."VIEW_COUNT"[NUMBER,22]
   6 - ROWID[ROWID,10]

2- Using New Indices
--------------------
Plan hash value: 986240798


-------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                              | Name           | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                       |                |     1 |       |    11  (10)| 00:00:01 |       |       |
|   1 |  SORT AGGREGATE                        |                |     1 |       |            |          |       |       |
|*  2 |   COUNT STOPKEY                        |                |       |       |            |          |       |       |
|   3 |    VIEW                                |                |     1 |       |    11  (10)| 00:00:01 |       |       |
|*  4 |     SORT ORDER BY STOPKEY              |                |     1 |   201 |    11  (10)| 00:00:01 |       |       |
|   5 |      TABLE ACCESS BY GLOBAL INDEX ROWID| SD_RES_ID_CASE |     1 |   201 |    10   (0)| 00:00:01 |     4 |     4 |
|*  6 |       INDEX RANGE SCAN                 | IDX$$_53800001 |     6 |       |     4   (0)| 00:00:01 |       |       |
-------------------------------------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1
   3 - SEL$2 / A@SEL$1
   4 - SEL$2
   5 - SEL$2 / T@SEL$2
   6 - SEL$2 / T@SEL$2

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter(ROWNUM<501)
   4 - filter(ROWNUM<501)
   6 - access("T"."CITY_ID"=:1 AND "T"."SUBJECT_ID"=:2 AND "T"."IS_SCHOOL_CHECK"=2 AND "T"."DELETE_FLAG"=0 AND
              "T"."FORBIDDEN_FLAG"=1 AND "T"."FROM_TYPE"='fromType.1s1k')
       filter(TBL$OR$IDX$PART$NUM(<?>,0,1,0,ROWID)=4)

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - (#keys=0) COUNT(*)[22]
   4 - (#keys=1) INTERNAL_FUNCTION("T"."VIEW_COUNT")[22]
   5 - "T"."VIEW_COUNT"[NUMBER,22]
   6 - ROWID[ROWID,10]

-------------------------------------------------------------------------------
ALTERNATIVE PLANS SECTION
-------------------------------------------------------------------------------

Plan 1
------

  Plan Origin                 :Cursor Cache
  Plan Hash Value             :4041534880
  Executions                  :39105
  Elapsed Time                :0.075 sec
  CPU Time                    :0.074 sec
  Buffer Gets                 :12014
  Disk Reads                  :0
  Disk Writes                 :0

Notes:
  1. Statistics shown are averaged over multiple executions.


------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                              | Name                | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                       |                     |     1 |       | 27105   (1)| 00:05:26 |       |       |
|   1 |  SORT AGGREGATE                        |                     |     1 |       |            |          |       |       |
|*  2 |   COUNT STOPKEY                        |                     |       |       |            |          |       |       |
|   3 |    VIEW                                |                     |     1 |       | 27105   (1)| 00:05:26 |       |       |
|*  4 |     SORT ORDER BY STOPKEY              |                     |     1 |   201 | 27105   (1)| 00:05:26 |       |       |
|*  5 |      TABLE ACCESS BY GLOBAL INDEX ROWID| SD_RES_ID_CASE      |     1 |   201 | 27104   (1)| 00:05:26 |     4 |     4 |
|*  6 |       INDEX RANGE SCAN                 | IDX1_RES_ID_CITY_ID | 28450 |       |   235   (0)| 00:00:03 |       |       |
------------------------------------------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1
   3 - SEL$2 / A@SEL$1
   4 - SEL$2
   5 - SEL$2 / T@SEL$2
   6 - SEL$2 / T@SEL$2

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter(ROWNUM<501)
   4 - filter(ROWNUM<501)
   5 - filter("T"."SUBJECT_ID"=:2 AND "T"."IS_SCHOOL_CHECK"=2 AND "T"."DELETE_FLAG"=0 AND "T"."FORBIDDEN_FLAG"=1 AND
              "T"."FROM_TYPE"='fromType.1s1k')
   6 - access("T"."CITY_ID"=:1)
       filter(TBL$OR$IDX$PART$NUM(<?>,0,1,0,ROWID)=4)

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - (#keys=0) COUNT(*)[22]
   4 - (#keys=1) INTERNAL_FUNCTION("T"."VIEW_COUNT")[22]
   5 - "T"."VIEW_COUNT"[NUMBER,22]
   6 - ROWID[ROWID,10]

Plan 2
------

  Plan Origin                 :Cursor Cache
  Plan Hash Value             :3664635048
  Executions                  :76345
  Elapsed Time                :0.231 sec
  CPU Time                    :0.229 sec
  Buffer Gets                 :41526
  Disk Reads                  :0
  Disk Writes                 :0

Notes:
  1. Statistics shown are averaged over multiple executions.
  2. The plan matches the original plan.


--------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                              | Name                        | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                       |                             |     1 |       |  3831   (1)| 00:00:46 |       |       |
|   1 |  SORT AGGREGATE                        |                             |     1 |       |            |          |       |       |
|*  2 |   COUNT STOPKEY                        |                             |       |       |            |          |       |       |
|   3 |    VIEW                                |                             |     1 |       |  3831   (1)| 00:00:46 |       |       |
|*  4 |     SORT ORDER BY STOPKEY              |                             |     1 |   201 |  3831   (1)| 00:00:46 |       |       |
|*  5 |      TABLE ACCESS BY GLOBAL INDEX ROWID| SD_RES_ID_CASE              |     1 |   201 |  3830   (1)| 00:00:46 |     4 |     4 |
|*  6 |       INDEX RANGE SCAN                 | ID1_ID_CASE_DF_ISC_SI_VI_TC |  3784 |       |    59   (0)| 00:00:01 |       |       |
--------------------------------------------------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1
   3 - SEL$2 / A@SEL$1
   4 - SEL$2
   5 - SEL$2 / T@SEL$2
   6 - SEL$2 / T@SEL$2

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter(ROWNUM<501)
   4 - filter(ROWNUM<501)
   5 - filter("T"."CITY_ID"=:1 AND "T"."FORBIDDEN_FLAG"=1 AND "T"."FROM_TYPE"='fromType.1s1k')
   6 - access("T"."DELETE_FLAG"=0 AND "T"."IS_SCHOOL_CHECK"=2 AND "T"."SUBJECT_ID"=:2)
       filter(TBL$OR$IDX$PART$NUM(<?>,0,1,0,ROWID)=4)

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - (#keys=0) COUNT(*)[22]
   4 - (#keys=1) INTERNAL_FUNCTION("T"."VIEW_COUNT")[22]
   5 - "T"."VIEW_COUNT"[NUMBER,22]
   6 - ROWID[ROWID,10]

Plan 3
------

  Plan Origin                 :Cursor Cache
  Plan Hash Value             :293581336
  Executions                  :15962
  Elapsed Time                :3.181 sec
  CPU Time                    :3.175 sec
  Buffer Gets                 :92713
  Disk Reads                  :0
  Disk Writes                 :0

Notes:
  1. Statistics shown are averaged over multiple executions.


-------------------------------------------------------------------------------------------------------------
| Id  | Operation                  | Name           | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |                |     1 |       |   173K  (1)| 00:34:37 |       |       |
|   1 |  SORT AGGREGATE            |                |     1 |       |            |          |       |       |
|*  2 |   COUNT STOPKEY            |                |       |       |            |          |       |       |
|   3 |    VIEW                    |                |     1 |       |   173K  (1)| 00:34:37 |       |       |
|*  4 |     SORT ORDER BY STOPKEY  |                |     1 |   201 |   173K  (1)| 00:34:37 |       |       |
|   5 |      PARTITION RANGE SINGLE|                |     1 |   201 |   173K  (1)| 00:34:37 |     4 |     4 |
|*  6 |       TABLE ACCESS FULL    | SD_RES_ID_CASE |     1 |   201 |   173K  (1)| 00:34:37 |     4 |     4 |
-------------------------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1
   3 - SEL$2 / A@SEL$1
   4 - SEL$2
   6 - SEL$2 / T@SEL$2

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter(ROWNUM<501)
   4 - filter(ROWNUM<501)
   6 - filter("T"."SUBJECT_ID"=:2 AND "T"."CITY_ID"=:1 AND "T"."IS_SCHOOL_CHECK"=2 AND
              "T"."DELETE_FLAG"=0 AND "T"."FORBIDDEN_FLAG"=1 AND "T"."FROM_TYPE"='fromType.1s1k')

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - (#keys=0) COUNT(*)[22]
   4 - (#keys=1) INTERNAL_FUNCTION("T"."VIEW_COUNT")[22]
   5 - "T"."VIEW_COUNT"[NUMBER,22]
   6 - "T"."VIEW_COUNT"[NUMBER,22]

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


Could you help me analyze it continuously?

Best Regards
Quanwen Zhao

and Connor said...

Check out v$sql_shared_cursor (and search asktom for the same). The column(s) that contains a Y indicates the cause.

It is the view that tells you why there are multiple children for the same SQL statement.

Rating

  (5 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Almost all of column(s)' value are 'N' except column "roll_invalid_mismatch"

Quanwen Zhao, July 05, 2018 - 9:46 am UTC

Hey, Connor :-)

According to your advice, I've queried the view "v$sql_shared_cursor" with sql_id = 'bg8pk89nc71x1', meanwhile I found the almost all of column(s)' value are 'N' except column "roll_invalid_mismatch", but I don't know the contents of the last column "reason" that comes from that view "v$sql_shared_cursor".

Here's my query result,

select sql_id, address, child_address, child_number, roll_invalid_mismatch from v$sql_shared_cursor where sql_id = 'bg8pk89nc71x1';

bg8pk89nc71x1 0000005675DD0178 000000567E25D018 0  Y  
bg8pk89nc71x1 0000005675DD0178 000000567BFE24C0 2  Y  
bg8pk89nc71x1 0000005675DD0178 000000567EACBF08 3  Y  
bg8pk89nc71x1 0000005675DD0178 000000567A3A5248 4  Y  


Best Regards
Quanwen Zhao
Connor McDonald
July 06, 2018 - 3:25 am UTC

From the docs: roll_invalid_mismatch

"Marked for rolling invalidation and invalidation window exceeded"

which is to do with how optimizer statistics works. Many versions ago, we would gather stats and every cursor (query) affected by the new stats would immediately have to reoptimized, which created a "parse storm" and mangle the server!

So we changed it - when we collect stats at (say) 5am, then queries that have tables impacted by the stats are slowly invalidated over a broad period (defaulting to 5 hours) in which they'll be reoptimized.

So 'roll_invalid_mismatch' means a cursor was somewhere in that 5hr period and exceeded its time threshold to be reoptimized (hence a new plan)

"INDEX RANGE SCAN" vs "TABLE ACCESS FULL"

Quanwen Zhao, July 06, 2018 - 8:07 am UTC

Hi, Connor

According to your detailed explanation, I've eventually understood "ROLL_INVALID_MISMATCH" is the concept of Oracle optimizer statistics work.

SQL ID : <b>bg8pk89nc71x1</b>
SQL Text : 
SELECT
    COUNT(*)
FROM
    (
        SELECT
            t.title,
            t.subject_id,
            t.cre_user_id,
            t.view_count,
            t.area_id,
            t.case_id
        FROM
            sd_res_id_case PARTITION ( year_mark4 ) t
        WHERE
                1 = 1
            AND
                t.delete_flag = '0'
            AND
                t.forbidden_flag = '1'
            AND
                t.is_school_check = '2'
            AND
                t.from_type = 'fromType.1s1k'
            AND
                t.city_id =:1
            AND
                t.subject_id =:2
        ORDER BY t.view_count DESC
    ) a
WHERE
    ROWNUM < 501
;


Nevertheless if you check that 3 number of execution plans, you'll find that the original execution plan has used "INDEX RANGE SCAN" at line id "6" and its index is "ID1_ID_CASE_DF_ISC_SI_VI_TC" (including 5 columns) , this index's circumstance is as follows,

set linesize 200
set pagesize 200
col column_name for a20
select column_name, column_position, column_length from dba_ind_columns where index_name = 'ID1_ID_CASE_DF_ISC_SI_VI_TC';

COLUMN_NAME          COLUMN_POSITION COLUMN_LENGTH
-------------------- --------------- -------------
DELETE_FLAG                        1            22
IS_SCHOOL_CHECK                    2            22
SUBJECT_ID                         3            40
VERSION_ID                         4            40
TEXTBOOK_CODE                      5            40

select column_name, num_distinct, last_analyzed from dba_tab_cols
where owner = 'SZD_RESOURCE_V2'
and table_name = 'SD_RES_ID_CASE'
and column_name in ('DELETE_FLAG', 'IS_SCHOOL_CHECK', 'SUBJECT_ID', 'VERSION_ID', 'TEXTBOOK_CODE')
order by 2 desc,1
;

COLUMN_NAME          NUM_DISTINCT LAST_ANALYZED
-------------------- ------------ -------------------
TEXTBOOK_CODE              128736 2018-07-05 22:00:24
VERSION_ID                    881 2018-07-05 22:00:24
SUBJECT_ID                     88 2018-07-05 22:00:24
IS_SCHOOL_CHECK                 4 2018-07-05 22:00:24
DELETE_FLAG                     2 2018-07-05 22:00:24


Next the second execution plan also adopts "INDEX RANGE SCAN" at line id "6" but it has used another index "IDX1_RES_ID_CITY_ID" (only one column) this time and its situation is below,

set linesize 200
set pagesize 200
col column_name for a20
select column_name, column_position, column_length from dba_ind_columns where index_name = 'IDX1_RES_ID_CITY_ID';

COLUMN_NAME          COLUMN_POSITION COLUMN_LENGTH
-------------------- --------------- -------------
CITY_ID                            1            40

select column_name, num_distinct, last_analyzed from dba_tab_cols where owner = 'SZD_RESOURCE_V2' and table_name = 'SD_RES_ID_CASE' and column_name = 'CITY_ID';

COLUMN_NAME          NUM_DISTINCT LAST_ANALYZED
-------------------- ------------ -------------------
CITY_ID                       411 2018-07-05 22:00:24


The third execution plan is about "TABLE ACCESS FULL" and its Cost(%CPU) is "173K".

The last execution plan comes from recommending method with SQLT Report and Oracle doesn't use it currently. Its index is "IDX$$_53800001" and you can also find some clues as follows,

Recommendation (estimated benefit: 99.71%)
  ------------------------------------------
  - Consider running the Access Advisor to improve the physical schema design
    or creating the recommended index.  If you choose to create the
    recommended index, consider dropping the index
    "SZD_RESOURCE_V2"."IDX1_RES_ID_CITY_ID" because it is a prefix of the
    recommended index.
    create index SZD_RESOURCE_V2.IDX$$_53800001 on
    SZD_RESOURCE_V2.SD_RES_ID_CASE("CITY_ID","SUBJECT_ID","IS_SCHOOL_CHECK","DE
    LETE_FLAG","FORBIDDEN_FLAG","FROM_TYPE");

  Rationale
  ---------
    Creating the recommended indices significantly improves the execution plan
    of this statement. However, it might be preferable to run "Access Advisor"
    using a representative SQL workload as opposed to a single statement. This
    will allow to get comprehensive index recommendations which takes into
    account index maintenance overhead and additional space consumption.


I think those two execution plan has been apparently different from each other (although they're all INDEX RANGE SCAN), maybe two different indexes have resulted in this root cause? Could I need to create that recommending index for improving performance (I see Cost(%CPU) will decrease to 11)?

Best Regards
Quanwen Zhao
Connor McDonald
July 09, 2018 - 4:45 am UTC

If your focus is to tune this *particular* SQL, then an index:

delete_flag,
is_school_check,
forbidden_flag,
subject_id,
from_type,
city_id,
view_count DESC

would probably do the trick, with some compression added depending on the distinct values for the columns above

"view_count DESC"?

Quanwen Zhao, July 09, 2018 - 8:55 am UTC

Hello, Connor

What does your mean, like this "view_count DESC"?

Best Regards
Quanwen Zhao
Connor McDonald
July 12, 2018 - 9:40 am UTC

"view_count desc" is adding that column to the index in descending fashion, eg

create index on MY_TABLE ( a, b, c desc, d , e )

My query "distinct value" on those six columns

Quanwen Zhao, July 10, 2018 - 3:55 am UTC

Sorry, Connor

"view_count" is one column of my original SQL QUERY statement.

According to your good advice I've also checked serial queries for "num_distinct", please taking a look at as follows,

set linesize 200
set pagesize 100
col column_name for a15
select column_name
       , num_distinct
       , density
       , num_nulls
       , num_buckets
       , last_analyzed
       , sample_size
       , global_stats
       , histogram
from dba_tab_col_statistics
where owner = 'SZD_RESOURCE_V2'
and table_name = 'SD_RES_ID_CASE'
and column_name in
('DELETE_FLAG'
 , 'IS_SCHOOL_CHECK'
 , 'FORBIDDEN_FLAG'
 , 'SUBJECT_ID'
 ,'FROM_TYPE'
 , 'CITY_ID'
 , 'VIEW_COUNT'
)
order by 2 desc
;

COLUMN_NAME     NUM_DISTINCT    DENSITY  NUM_NULLS NUM_BUCKETS LAST_ANALYZED       SAMPLE_SIZE GLOBAL HISTOGRAM
--------------- ------------ ---------- ---------- ----------- ------------------- ----------- ------ ------------------------------
VIEW_COUNT              4343 .000230256          0           1 2018-07-05 22:00:24    20371140 YES    NONE
CITY_ID                  411 .002949853      13885         254 2018-07-05 22:00:24        9644 YES    HEIGHT BALANCED
SUBJECT_ID                88 2.4745E-08         33          70 2018-07-05 22:00:24        9649 YES    FREQUENCY
IS_SCHOOL_CHECK            4 2.4745E-08          0           4 2018-07-05 22:00:24        9649 YES    FREQUENCY
FROM_TYPE                  2 2.4745E-08          0           1 2018-07-05 22:00:24        9649 YES    FREQUENCY
DELETE_FLAG                2 2.4745E-08          0           2 2018-07-05 22:00:24        9649 YES    FREQUENCY
FORBIDDEN_FLAG             2 2.4743E-08          0           2 2018-07-05 22:00:24        9650 YES    FREQUENCY

7 rows selected.


If I wanna create the composite index, how to arrange the order of those total six columns?

Best Regards
Quanwen Zhao

Performing well after creating composite index

Quanwen Zhao, July 12, 2018 - 2:05 am UTC

Hello, Connor

Afterwards I've created the composite index "IDX$$_53800001_by_STA" and my SQL statement performed well this time.

set timing on
create index IDX$$_53800001_by_STA on SD_RES_ID_CASE("CITY_ID","SUBJECT_ID","IS_SCHOOL_CHECK","DELETE_FLAG","FORBIDDEN_FLAG","FROM_TYPE") online;

Index created.

00:05:01 elapsed.

SELECT /*+gather_plan_statistics */ COUNT(*) FROM ( SELECT t.title, t.subject_id, t.cre_user_id, t.view_count, t.area_id, t.case_id FROM sd_res_id_case PARTITION (year_mark4) t WHERE 1 = 1 AND t.delete_flag = '0' AND t.forbidden_flag = '1' AND t.is_school_check = '2' AND t.from_type = 'fromType.1s1k' AND t.city_id = '995DC6B6-C471-2091-F8CF-D612184D54DE' AND t.subject_id = 'subject.0059' ORDER BY t.view_count DESC ) a WHERE ROWNUM < 501;

  COUNT(*)
----------
         0

select * from table(dbms_xplan.display_cursor(NULL,NULL,'ALLSTATS ALL'));

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------
SQL_ID  7v2hhd6m2d9zk, child number 0
-------------------------------------

...... Omitted.

Plan hash value: 3971318438

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                              | Name                  | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | Pstart| Pstop | A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem |  O/1/M   |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                       |                       |      1 |        |       |     6 (100)|        |        |       |      1 |00:00:00.01 |       4 |      2 |       |       |          |
|   1 |  SORT AGGREGATE                        |                       |      1 |      1 |       |            |        |        |       |      1 |00:00:00.01 |       4 |      2 |       |       |          |
|*  2 |   COUNT STOPKEY                        |                       |      1 |        |       |            |        |        |       |      0 |00:00:00.01 |       4 |      2 |       |       |          |
|   3 |    VIEW                                |                       |      1 |      1 |       |     6  (17)|00:00:01|        |       |      0 |00:00:00.01 |       4 |      2 |       |       |          |
|*  4 |     SORT ORDER BY STOPKEY              |                       |      1 |      1 |   201 |     6  (17)|00:00:01|        |       |      0 |00:00:00.01 |       4 |      2 |  1024 |  1024 |     1/0/0|
|   5 |      TABLE ACCESS BY GLOBAL INDEX ROWID| SD_RES_ID_CASE        |      1 |      1 |   201 |     5   (0)|00:00:01|      4 |     4 |      0 |00:00:00.01 |       4 |      2 |       |       |          |
|*  6 |       INDEX RANGE SCAN                 | IDX$$_53800001_BY_STA |      1 |      1 |       |     4   (0)|00:00:01|        |       |      0 |00:00:00.01 |       4 |      2 |       |       |          |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1
   3 - SEL$2 / A@SEL$1
   4 - SEL$2
   5 - SEL$2 / T@SEL$2
   6 - SEL$2 / T@SEL$2

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter(ROWNUM<501)
   4 - filter(ROWNUM<501)
   6 - access("T"."CITY_ID"='995DC6B6-C471-2091-F8CF-D612184D54DE' AND "T"."SUBJECT_ID"='subject.0059' AND "T"."IS_SCHOOL_CHECK"=2 AND "T"."DELETE_FLAG"=0 AND "T"."FORBIDDEN_FLAG"=1 AND
              "T"."FROM_TYPE"='fromType.1s1k')
       filter(TBL$OR$IDX$PART$NUM(<?>,0,1,0,ROWID)=4)

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - (#keys=0) COUNT(*)[22]
   4 - (#keys=1) INTERNAL_FUNCTION("T"."VIEW_COUNT")[22]
   5 - "T"."VIEW_COUNT"[NUMBER,22]
   6 - ROWID[ROWID,10]


50 rows selected.


Thank you very much.

Best Regards
Quanwen Zhao

More to Explore

Performance

Get all the information about database performance in the Database Performance guide.