简体   繁体   中英

Oracle Query optimization for this query

Please suggest how to improve below query /index for faster results.

Query

SELECT Tab1.pk, Tab1.c_RetryCount, Tab1.c_TimeCreated  
  FROM Table1 Tab1  
 WHERE ( ( Tab1.c_node = :1 
           OR Tab1.c_node IS NULL ) 
       AND ( ( Tab1.c_RetryCount < :2 
               AND Tab1.c_TimeUpdated < :3 ) 
            OR Tab1.c_RetryCount < :4 ) 
       AND Tab1.c_SentStatus = :5 ) 
   AND ( Tab1.c_Active = 1 ) 
   AND ( Tab1.c_DelFlag = 0 ) 
   AND ( Tab1.c_Shard = :6 )  
 ORDER BY Tab1.c_RetryCount ASC, Tab1.c_TimeCreated ASC

Plan hash value: 2132878353


| Id  | Operation                     | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |                 |       |       |     4 (100)|          |
|   1 |  SORT ORDER BY                |                 |    43 |  2279 |     4  (25)| 00:00:01 |
|   2 |   CONCATENATION               |                 |       |       |            |          |
|*  3 |    TABLE ACCESS BY INDEX ROWID| Table1          |     1 |    53 |     1   (0)| 00:00:01 |
|*  4 |     INDEX RANGE SCAN          | I_VOY52S_H881K4 |     1 |       |     1   (0)| 00:00:01 |
|*  5 |    TABLE ACCESS BY INDEX ROWID| Table1          |    42 |  2226 |     2   (0)| 00:00:01 |
|*  6 |     INDEX RANGE SCAN          | I_VOY52S_H881K4 |     2 |       |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):


   3 - filter(("Tab1"."c_DelFlag"=0 AND "Tab1"."c_ACTIVE"=1))
   4 - access("Tab1"."c_Shard"=:6 AND "Tab1"."c_node" IS NULL 
              AND "Tab1"."c_SENTSTATUS"=:5)
       filter(("Tab1"."c_SENTSTATUS"=:5 AND ("Tab1"."c_RETRYCOUNT"<:4 OR 
              ("Tab1"."c_TIMEUPDATED"<:3 AND "Tab1"."c_RETRYCOUNT"<:2))))
   5 - filter(("Tab1"."c_DelFlag"=0 AND "Tab1"."c_ACTIVE"=1))
   6 - access("Tab1"."c_Shard"=:6 AND "Tab1"."c_node"=:1 AND 
              "Tab1"."c_SENTSTATUS"=:5)
       filter(("Tab1"."c_SENTSTATUS"=:5 AND ("Tab1"."c_RETRYCOUNT"<:4 OR 
              ("Tab1"."c_TIMEUPDATED"<:3 AND "Tab1"."c_RETRYCOUNT"<:2)) AND 
              LNNVL("Tab1"."c_node" IS NULL)))

Table Table1 indexes:

  I_VOY52S_19HS9Y5 (c_SENTSTATUS, c_ACTIVE, c_DelFlag) 
  I_VOY52S_1CPSX8O (c_node) 
  I_VOY52S_H881K4 (c_Shard, c_node, c_RETRYCOUNT, c_TIMEUPDATED, c_SENTSTATUS) 
  P_VOY52S_142KZ99 (pk) 

Other than c_Shard, the other two single-value filters being applied to every row use c_Active, c_DelFlag. So, it is a pretty good guess that adding these to the I_VOY52S_H881K4 index will improve performance of this one query.

Or, a new index :

    I_VOY52S_XXXXX (c_Shard, c_Active, c_DelFlag, 
                    c_node, c_RETRYCOUNT, c_TIMEUPDATED, c_SENTSTATUS) 

You could even throw in pk and c_timeCreated near the end to keep the query index-only.

Of course, creating a new index like that might be totally impractical when one considers other query, or data-volume; but, since you did not mention this, I'm assuming zero cost to having another index that's perfect for this one query.

So, you'd get:

    I_VOY52S_XXXXX (c_Shard, c_Active, c_DelFlag, 
                    c_node, c_RETRYCOUNT, c_TIMEUPDATED, c_SENTSTATUS, 
                    c_timecreated, pk) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM