2013-04-22不适当的索引导致的性能问题--影响CBO的判断

         现场反馈系统慢,做了一个AWR报告,平时上班时间一个小时正常DB time为100min,现在已经远远超过这个数。数据库服务器CPU有4个。

 Snap IdSnap TimeSessionsCursors/Session
Begin Snap:3135522-Apr-13 11:00:489121.4
End Snap:3135622-Apr-13 12:01:0110517.5
Elapsed: 60.21 (mins)  
DB Time: 1,777.30 (mins)  

EventWaitsTime(s)Avg Wait(ms)% Total Call TimeWait Class
latch: cache buffers chains34,98311,72033511.0Concurrency
CPU time 11,527 10.8 
latch free44288200.1Other
db file sequential read61,933711.1User I/O
db file scattered read13,744151.0User I/O

      可以看到SQL的执行时间远远大于SQL消耗CPU的时间。老问题,单条SQL逻辑读过高,在并发的情况下,产生大量资源争用,平均每次逻辑读1,109,335。

Elapsed Time (s)CPU Time (s)Executions Elap per Exec (s) % Total DB TimeSQL IdSQL ModuleSQL Text
44,5594,145113394.3241.79435xza3c04ac9 SELECT GG_JOB_ITEM.*, PROD_...
44,5514,392113394.2541.788jjqdn6bw4f2p SELECT COUNT(1) C FROM GG_JOB...

问题SQL语句:

SELECT COUNT(1) C
  FROM GG_JOB_ITEM, GG_JOB_PATROL_DETAIL
 WHERE GG_JOB_ITEM.TASK_ID = GG_JOB_PATROL_DETAIL.TASK_ID(+)
   AND GG_JOB_ITEM.TASK_KIND = :1
   AND GG_JOB_ITEM.TASK_SOURCE = :2
   AND GG_JOB_ITEM.IS_COMPLETE = 5
   AND NOT EXISTS (SELECT 1
          FROM GG_JOB_ITEM A
         WHERE A.TASK_KIND = :3
           AND A.TASK_SOURCE != :4
           AND A.TASK_SOURCE_ID = GG_JOB_ITEM.TASK_ID)
   AND EXISTS
 (SELECT 1
          FROM GG_JOB_ITEM B
         WHERE B.TASK_KIND = :5
           AND B.IS_COMPLETE != 5
           AND B.TASK_ID = GG_JOB_ITEM.TASK_SOURCE_ID)
   AND ((GG_JOB_ITEM.TASK_BEGIN_DATE >= :6 AND
       GG_JOB_ITEM.TASK_BEGIN_DATE <= :7) OR
       (GG_JOB_ITEM.TASK_END_DATE >= :8 AND
       GG_JOB_ITEM.TASK_END_DATE <= :9) OR
       (GG_JOB_ITEM.TASK_BEGIN_DATE <= :10 AND
       GG_JOB_ITEM.TASK_END_DATE >= :11))
   AND GG_JOB_ITEM.TASK_KIND = :12
   AND GG_JOB_ITEM.IS_COMPLETE = :13
   AND GG_JOB_ITEM.TASK_TYPE IN
       (1, 2, 6, 4, 21, 3, 7, 8, 9, 22, 23, 26, 29, 11, 12, 14, 19, 24);

 ----------------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name                        | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |                             |       |       |  1353 (100)|          |
|   1 |  SORT AGGREGATE                  |                             |     1 |    63 |            |          |
|*  2 |   FILTER                         |                             |       |       |            |          |
|   3 |    NESTED LOOPS ANTI             |                             |     1 |    63 |  1353   (1)| 00:00:17 |
|   4 |     NESTED LOOPS SEMI            |                             |     1 |    52 |  1352   (1)| 00:00:17 |
|   5 |      NESTED LOOPS OUTER          |                             |     1 |    42 |  1351   (1)| 00:00:17 |
|*  6 |       TABLE ACCESS BY INDEX ROWID| GG_JOB_ITEM              |     1 |    37 |  1350   (1)| 00:00:17 |   
|*  7 |        INDEX RANGE SCAN          | INDEX_TASK_KIND             |   107K|       |    63   (0)| 00:00:01 |
|*  8 |       INDEX UNIQUE SCAN          | PK_GG_JOB_PATROL_DETAILA |     1 |     5 |     1   (0)| 00:00:01 |   
|*  9 |      TABLE ACCESS BY INDEX ROWID | GG_JOB_ITEM              | 86225 |   842K|     1   (0)| 00:00:01 |   
|* 10 |       INDEX UNIQUE SCAN          | PK_GG_JOB_ITEM           |     1 |       |     1   (0)| 00:00:01 |   
|* 11 |     TABLE ACCESS BY INDEX ROWID  | GG_JOB_ITEM              |   107K|  1151K|     1   (0)| 00:00:01 |   
|* 12 |      INDEX RANGE SCAN            | INDEX_TASK_KIND             |     3 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------

       对表GG_JOB_ITEM进行分析,记录有三十多万,有8个索引,其中在TASK_KIND和TASK_TYPE上建了索引,TASK_KIND只有3个值,TASK_TYPE只有20个值,选择性如此差的字段不能建索引,处理方法是全部drop。
      只是删除了两个索引,更新表的统计信息后再次执行SQL,执行计划为:

--------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name                        | Rows  | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |                             |     3 |   966 |  4980   (2)|
|   1 |  NESTED LOOPS OUTER           |                             |     3 |   966 |  4980   (2)|
|   2 |   NESTED LOOPS SEMI           |                             |     3 |   891 |  4979   (2)|
|   3 |    HASH JOIN ANTI             |                             |   233 | 66871 |  4932   (2)|
|   4 |     TABLE ACCESS FULL         | PROD_TASK_ITEM              |   234 | 64584 |  2466   (2)|
|   5 |     TABLE ACCESS FULL         | PROD_TASK_ITEM              |   105K|  1129K|  2465   (2)|
|   6 |    TABLE ACCESS BY INDEX ROWID| PROD_TASK_ITEM              |  1347 | 13470 |     1   (0)|
|   7 |     INDEX UNIQUE SCAN         | PK_PROD_TASK_ITEM           |     1 |       |     1   (0)|
|   8 |   TABLE ACCESS BY INDEX ROWID | PROD_TASK_PATROL_DETAIL     |     1 |    25 |     1   (0)|
|   9 |    INDEX UNIQUE SCAN          | PK_PROD_TASK_PATROL_DETAILA |     1 |       |     1   (0)|
--------------------------------------------------------------------------------------------------
统计信息                                                                                          
----------------------------------------------------------                                        
          1  recursive calls                                                                      
          0  db block gets                                                                        
      22722  consistent gets                                                                      
         27  physical reads                                                                       
          0  redo size                                                                            
      17193  bytes sent via SQL*Net to client                                                     
        281  bytes received via SQL*Net from client                                               
          8  SQL*Net roundtrips to/from client                                                    
          0  sorts (memory)                                                                       
          0  sorts (disk)                                                                         
         93  rows processed                                                                       

       优化后SQL执行时间从38s优化到0.76s,逻辑读从1,109,335降低到22722。比较两次的执行计划,可以看到是不必要的索引帮了倒忙,影响了CBO的判断。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值