【SQL优化】四月份培训的一个sql优化案例3

下面的语句同样是生产环境的慢sql,通过我对大家的培训,把部分慢sql给当场干掉,成功阻止了双节点cpu偶尔过高的问题:
直接上当时的材料:
原始sql语句:
select sum(aaa.acceptid)
  from (select count(c.accept_id) as acceptid
          from cct_log_eomsintf_201503 c,
               (select b.accept_id accept_id,
                       max(b.creation_time) creation_time
                  from cct_log_eomsintf_201503 b
                 where exists (select 1
                          from cct_log_eomsintf_201503 a
                         where a.exception_info like '%启动保障机制%'
                           and a.accept_id = b.accept_id)
                 group by b.accept_id) d,
               cct_wf_accept_201503 e
         where c.accept_id = d.accept_id
           and c.creation_time = d.creation_time
           and c.accept_id = e.accept_id
           and e.ring <> 128
           and e.ring <> 119
           and c.exception_info like '%启动保障机制%'
        union all
        select count(c.accept_id) as acceptid
          from cct_log_eomsintf_201504 c,
               (select b.accept_id accept_id,
                       max(b.creation_time) creation_time
                  from cct_log_eomsintf_201504 b
                 where exists (select 1
                          from cct_log_eomsintf_201504 a
                         where a.exception_info like '%启动保障机制%'
                           and a.accept_id = b.accept_id)
                 group by b.accept_id) d,
               cct_wf_accept_201504 e
         where c.accept_id = d.accept_id
           and c.creation_time = d.creation_time
           and c.accept_id = e.accept_id
           and e.ring <> 128
           and e.ring <> 119
           and c.exception_info like '%启动保障机制%') aaa
 
Execution Plan
----------------------------------------------------------
 
------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name                     | Rows  | Bytes | Cost (%CPU)|
------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |                          |     1 |    13 | 73783   (1)|
|   1 |  SORT AGGREGATE                      |                          |     1 |    13 |            |
|   2 |   VIEW                               |                          |     2 |    26 | 73783   (1)|
|   3 |    UNION-ALL                         |                          |       |       |            |
|   4 |     SORT AGGREGATE                   |                          |     1 |    24 |            |
|   5 |      VIEW                            |                          |     1 |    24 | 44412   (1)|
|*  6 |       FILTER                         |                          |       |       |            |
|   7 |        HASH GROUP BY                 |                          |     1 |   134 | 44412   (1)|
|*  8 |         HASH JOIN RIGHT SEMI         |                          |   329K|    42M| 44399   (1)|
|*  9 |          TABLE ACCESS FULL           | CCT_LOG_EOMSINTF_201503  | 20242 |   612K| 16662   (1)|
|* 10 |          HASH JOIN                   |                          |   329K|    32M| 27735   (1)|
|* 11 |           TABLE ACCESS BY INDEX ROWID| CCT_LOG_EOMSINTF_201503  |     1 |    51 |     8   (0)|
|  12 |            NESTED LOOPS              |                          |  3757 |   297K| 11074   (1)|
|* 13 |             INDEX FAST FULL SCAN     | IDX_CCT_WF_ACCEPT_201503 |  3331 | 99930 |  1069   (1)|
|* 14 |             INDEX RANGE SCAN         | ACCEPT_ID_IDX_201503     |     6 |       |     2   (0)|
|  15 |           TABLE ACCESS FULL          | CCT_LOG_EOMSINTF_201503  |   404K|  8697K| 16658   (1)|
|  16 |     SORT AGGREGATE                   |                          |     1 |    24 |            |
|  17 |      VIEW                            |                          |     1 |    24 | 29371   (1)|
|* 18 |       FILTER                         |                          |       |       |            |
|  19 |        HASH GROUP BY                 |                          |     1 |   120 | 29371   (1)|
|* 20 |         HASH JOIN RIGHT SEMI         |                          | 14719 |  1724K| 29370   (1)|
|* 21 |          TABLE ACCESS FULL           | CCT_LOG_EOMSINTF_201504  | 11576 |   271K|  9536   (1)|
|* 22 |          HASH JOIN                   |                          | 61608 |  5775K| 19832   (1)|
|* 23 |           HASH JOIN                  |                          | 11575 |   836K| 10297   (1)|
|* 24 |            TABLE ACCESS FULL         | CCT_LOG_EOMSINTF_201504  | 11576 |   497K|  9536   (1)|
|* 25 |            INDEX FAST FULL SCAN      | IDX_CCT_WF_ACCEPT_201504 | 22933 |   671K|   759   (1)|
|  26 |           TABLE ACCESS FULL          | CCT_LOG_EOMSINTF_201504  |   231K|  4973K|  9534   (1)|
------------------------------------------------------------------------------------------------------
 
优化前:
select count(c.accept_id) as acceptid
  from cct_log_eomsintf_201504 c,
       (select b.accept_id accept_id, max(b.creation_time) creation_time
          from cct_log_eomsintf_201504 b
         where exists (select 1
                  from cct_log_eomsintf_201504 a
                 where a.exception_info like '%启动保障机制%'
                   and a.accept_id = b.accept_id)
         group by b.accept_id) d,
       cct_wf_accept_201504 e
where c.accept_id = d.accept_id
   and c.creation_time = d.creation_time
   and c.accept_id = e.accept_id
   and e.ring <> 128
   and e.ring <> 119
   and c.exception_info like '%启动保障机制%'
 
Execution Plan
----------------------------------------------------------
---------------------------------------------------------------------------------------------
| Id  | Operation                   | Name                     | Rows  | Bytes | Cost (%CPU)|
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                          |     1 |    24 | 29371   (1)|
|   1 |  SORT AGGREGATE             |                          |     1 |    24 |            |
|   2 |   VIEW                      |                          |     1 |    24 | 29371   (1)|
|*  3 |    FILTER                   |                          |       |       |            |
|   4 |     HASH GROUP BY           |                          |     1 |   120 | 29371   (1)|
|*  5 |      HASH JOIN RIGHT SEMI   |                          | 14719 |  1724K| 29370   (1)|
|*  6 |       TABLE ACCESS FULL     | CCT_LOG_EOMSINTF_201504  | 11576 |   271K|  9536   (1)|
|*  7 |       HASH JOIN             |                          | 61608 |  5775K| 19832   (1)|
|*  8 |        HASH JOIN            |                          | 11575 |   836K| 10297   (1)|
|*  9 |         TABLE ACCESS FULL   | CCT_LOG_EOMSINTF_201504  | 11576 |   497K|  9536   (1)|
|* 10 |         INDEX FAST FULL SCAN| IDX_CCT_WF_ACCEPT_201504 | 22933 |   671K|   759   (1)|
|  11 |        TABLE ACCESS FULL    | CCT_LOG_EOMSINTF_201504  |   231K|  4973K|  9534   (1)|
--------------------------------------------------------------------------------------------- 
Statistics
----------------------------------------------------------
          2  recursive calls
          0  db block gets
     139867  consistent gets
          0  physical reads
        768  redo size
        515  bytes sent via SQL*Net to client
        492  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
 
分析:
很明显,CCT_LOG_EOMSINTF_201504表不应该被扫描三次,并且还是全表扫描。如果这个表非常大,在OLAP系统就容易搞死人了。
那么怎么想办法,只让CCT_LOG_EOMSINTF_201504被扫描一次呢?答案,使用with as的方式来优化
 
优化后:
with t1 as
(select accept_id, creation_time, exception_info
    from cct_log_eomsintf_201504
   where exception_info like '%启动保障机制%')
select count(c.accept_id) as acceptid
  from t1 c,
       (select b.accept_id accept_id, max(b.creation_time) creation_time
          from t1 b
         where exists (select 1 from t1 a where a.accept_id = b.accept_id)
         group by b.accept_id) d,
       cct_wf_accept_201504 e
where c.accept_id = d.accept_id
   and c.creation_time = d.creation_time
   and c.accept_id = e.accept_id
   and e.ring <> 128
   and e.ring <> 119
 
优化后:
 
Execution Plan
---------------------------------------------------------
---------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name                        | Rows  | Bytes | Cost (%CPU)|
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                             |     1 |    84 |  9580   (1)|
|   1 |  TEMP TABLE TRANSFORMATION     |                             |       |       |            |
|   2 |   LOAD AS SELECT               | CCT_WF_ACCEPT_201504        |       |       |            |
|*  3 |    TABLE ACCESS FULL           | CCT_LOG_EOMSINTF_201504     | 11576 |   361K|  9536   (1)|
|   4 |   SORT AGGREGATE               |                             |     1 |    84 |            |
|   5 |    NESTED LOOPS                |                             |     1 |    84 |    44   (7)|
|*  6 |     HASH JOIN                  |                             |     1 |    66 |    42   (8)|
|   7 |      VIEW                      |                             | 11576 |   373K|    13   (0)|
|   8 |       TABLE ACCESS FULL        | SYS_TEMP_0FD9D69AB_7BCA41BF | 11576 |   361K|    13   (0)|
|   9 |      VIEW                      |                             | 11576 |   373K|    28   (8)|
|  10 |       HASH GROUP BY            |                             | 11576 |   418K|    28   (8)|
|* 11 |        HASH JOIN RIGHT SEMI    |                             | 11576 |   418K|    27   (4)|
|  12 |         VIEW                   |                             | 11576 |   158K|    13   (0)|
|  13 |          TABLE ACCESS FULL     | SYS_TEMP_0FD9D69AB_7BCA41BF | 11576 |   361K|    13   (0)|
|  14 |         VIEW                   |                             | 11576 |   260K|    13   (0)|
|  15 |          TABLE ACCESS FULL     | SYS_TEMP_0FD9D69AB_7BCA41BF | 11576 |   361K|    13   (0)|
|* 16 |     TABLE ACCESS BY INDEX ROWID| CCT_WF_ACCEPT_201504        |     1 |    18 |     2   (0)|
|* 17 |      INDEX UNIQUE SCAN         | PK_WFKACCEPT_AID_201504     |     1 |       |     1   (0)|
---------------------------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
        123  recursive calls
         11  db block gets
      45740  consistent gets
          1  physical reads
       1768  redo size
        515  bytes sent via SQL*Net to client
        492  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
 
一致读取,从13w下降到4w。

还有像下面的sql,改写方式一致:
select count(*)
  from (select t1.accept_id_1860, count(1)
          from (select a.accept_id_1860, a.accept_id
                  from cct_log_appealintf1860_201504 a
                 where not exists (select 1
                          from cct_wf_accept_201504 b
                         where a.accept_id = b.accept_id)
                   and a.reqtype = '11') t1
         group by t1.accept_id_1860
        intersect
        select t2.accept_id_1860, count(1)
          from cct_log_appealintf1860_201504 t2
         where t2.accept_id_1860 in
               (select a.accept_id_1860
                  from cct_log_appealintf1860_201504 a
                 where not exists (select 1
                          from cct_wf_accept_201504 b
                         where a.accept_id = b.accept_id)
                   and a.reqtype = '11')
           and t2.reqtype = '11'
         group by t2.accept_id_1860) t3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值