0

请建议如何改进以下查询/索引以获得更快的结果。

询问

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

计划哈希值: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 |
-------------------------------------------------------------------------------------------------

谓词信息(由操作 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)))

表 Table1 索引:

  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) 
4

1 回答 1

0

除了 c_Shard,其他两个应用于每一行的单值过滤器使用 c_Active、c_DelFlag。因此,将这些添加到 I_VOY52S_H881K4 索引将提高这一查询的性能是一个很好的猜测。

或者,一个新的索引:

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

您甚至可以在接近尾声时加入 pk 和 c_timeCreated 以保持查询仅索引。

当然,当考虑其他查询或数据量时,创建这样的新索引可能完全不切实际。但是,由于您没有提到这一点,我假设拥有另一个非常适合这个查询的索引的成本为零。

所以,你会得到:

    I_VOY52S_XXXXX (c_Shard, c_Active, c_DelFlag, 
                    c_node, c_RETRYCOUNT, c_TIMEUPDATED, c_SENTSTATUS, 
                    c_timecreated, pk) 
于 2013-06-06T13:29:07.013 回答