记一次优化, 纠正SQ的L执行计划优化




SELECT 
 a.id AS order_id ,b.s_id AS bill_id,
 d.id AS sub_order_id,
 d.deal_oper_id
  FROM EM_ORDER         PARTITION(EM_ORDER_201611) A,
       M_101_ID_2_GID   B,
       ER_ORDER_ORDER   C,
       EM_ORDER         D,
       EE_ORDER_PF_WORK E
 WHERE A.SPEC_ID = 3010200004
   AND A.ID = B.T_ID
   AND A.STATUS_ID = 1000007
     AND  A.COMPLETE_TIME  >=  TO_DATE('2016-11-14 00:00:00',   'YYYY-MM-DD HH24:MI:SS')
   and A.COMPLETE_TIME  <=  TO_DATE('2016-11-14 23:59:59',   'YYYY-MM-DD HH24:MI:SS')
   AND A.ID = C.A_ORDER_ID
   AND C.B_ORDER_ID = D.ID
   AND D.ID = E.ORDER_ID
   AND e.work_type_id = 1001411
    AND (   d.deal_oper_id IS NULL --无处理人
        OR (SELECT f_chk_idcard(x.identity_number)
                  FROM dm_staff x
                 WHERE x.id = d.deal_oper_id) = 0 --处理人身份证不合法
       );

表大小:
        size_mb         segement_name

1 4595.0625 EE_ORDER_PF_WORK
2 40159.0625 EM_ORDER
3 20059.0625 ER_ORDER_ORDER
4 20770.0625 M_101_ID_2_GID
  
dm_staff  不值一提,  20万条数据。
 


1 Plan hash value: 309883988

3 --------------------------------------------------------------------------------------------------------------------------------------------
4 | Id  | Operation                                 | Name                   | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |
5 --------------------------------------------------------------------------------------------------------------------------------------------
6 |   0 | SELECT STATEMENT                          |                        |     1 |   130 |       |  1218K  (1)| 04:03:44 |       |       |
7 |*  1 |  FILTER                                   |                        |       |       |       |            |          |       |       |
8 |   2 |   NESTED LOOPS                            |                        | 21005 |  2666K|       |  1166K  (1)| 03:53:19 |       |       |
9 |   3 |    NESTED LOOPS                           |                        | 21791 |  2666K|       |  1166K  (1)| 03:53:19 |       |       |
10 |*  4 |     HASH JOIN                             |                        | 21791 |  2234K|    17M|  1079K  (1)| 03:35:53 |       |       |
11 |   5 |      NESTED LOOPS                         |                        |   183K|    15M|       |   907K  (1)| 03:01:32 |       |       |
12 |   6 |       NESTED LOOPS                        |                        |   183K|    15M|       |   907K  (1)| 03:01:32 |       |       |
13 |   7 |        NESTED LOOPS                       |                        |   183K|    11M|       |   358K  (1)| 01:11:37 |       |       |
14 |*  8 |         TABLE ACCESS BY GLOBAL INDEX ROWID| EM_ORDER               |   106K|  3631K|       | 39284   (1)| 00:07:52 |     8 |     8 |
15 |*  9 |          INDEX RANGE SCAN                 | IDX_EM_ORDER_COMP_TIME | 44669 |       |       |   330   (0)| 00:00:04 |       |       |
16 |* 10 |         INDEX RANGE SCAN                  | IDX_ER_ORDER_ORDER_OO  |     2 |    56 |       |     3   (0)| 00:00:01 |       |       |
17 |* 11 |        INDEX UNIQUE SCAN                  | PK_EM_ORDER            |     1 |       |       |     2   (0)| 00:00:01 |       |       |
18 |  12 |       TABLE ACCESS BY GLOBAL INDEX ROWID  | EM_ORDER               |     1 |    26 |       |     3   (0)| 00:00:01 | ROWID | ROWID |
19 |  13 |      PARTITION RANGE ALL                  |                        |    10M|   161M|       |   156K  (1)| 00:31:22 |     1 |    10 |
20 |* 14 |       TABLE ACCESS FULL                   | EE_ORDER_PF_WORK       |    10M|   161M|       |   156K  (1)| 00:31:22 |     1 |    10 |
21 |* 15 |     INDEX RANGE SCAN                      | IDX_101_T_ID           |     1 |       |       |     3   (0)| 00:00:01 |       |       |
22 |  16 |    TABLE ACCESS BY GLOBAL INDEX ROWID     | M_101_ID_2_GID         |     1 |    25 |       |     4   (0)| 00:00:01 | ROWID | ROWID |
23 |  17 |   TABLE ACCESS BY INDEX ROWID             | DM_STAFF               |     1 |    20 |       |     3   (0)| 00:00:01 |       |       |
24 |* 18 |    INDEX UNIQUE SCAN                      | PK_DM_STAFF            |     1 |       |       |     2   (0)| 00:00:01 |       |       |
25 --------------------------------------------------------------------------------------------------------------------------------------------
26 
27 Predicate Information (identified by operation id):
28 ---------------------------------------------------
29 
30    1 - filter( (SELECT "F_CHK_IDCARD"("X"."IDENTITY_NUMBER") FROM "QWZW_ER"."DM_STAFF" "X" WHERE "X"."ID"=:B1)=0)
31    4 - access("D"."ID"="E"."ORDER_ID")
32    8 - filter("A"."SPEC_ID"=3010200004 AND "A"."STATUS_ID"=1000007)
33    9 - access("A"."COMPLETE_TIME">=TO_DATE(' 2016-11-16 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "A"."COMPLETE_TIME"<=TO_DATE('
34               2016-11-16 23:59:59', 'syyyy-mm-dd hh24:mi:ss'))
35        filter(TBL$OR$IDX$PART$NUM("QWZW_ER"."EM_ORDER",0,1,0,ROWID)=8)
36   10 - access("A"."ID"="C"."A_ORDER_ID")
37   11 - access("C"."B_ORDER_ID"="D"."ID")
38   14 - filter("E"."WORK_TYPE_ID"=1001411)
39   15 - access("A"."ID"="B"."T_ID")
40        filter("B"."T_ID" IS NOT NULL)
41   18 - access("X"."ID"=:B1)


---- 这个估计 7  8 小时都跑不完。  反正我执行过1个多小时, 受不了杀了。    如果你不能一眼看出 这个的问题的话, 证明 你还需要修炼。  信不信 有你

性能问题在  4 ,   14。  
 

改SQL:为

    SELECT  
  '开通单' AS spec_name,
 a.id AS order_id ,b.s_id AS bill_id,
 d.id AS sub_order_id,
 ---x.s_id  task_id,
 d.deal_oper_id 

  FROM EM_ORDER         PARTITION(EM_ORDER_201611) A,
       M_101_ID_2_GID   B,
       ER_ORDER_ORDER   C,
       EM_ORDER         D
 WHERE A.SPEC_ID = 3010200004
   AND A.ID = B.T_ID
   AND A.STATUS_ID = 1000007
   AND  A.COMPLETE_TIME  >=  TO_DATE('2016-11-18 00:00:00',   'YYYY-MM-DD HH24:MI:SS')
   and A.COMPLETE_TIME  <=  TO_DATE('2016-11-18 23:59:59',   'YYYY-MM-DD HH24:MI:SS')
   AND A.ID = C.A_ORDER_ID
   AND C.B_ORDER_ID = D.ID
   AND  exists( select   1 from   EE_ORDER_PF_WORK E  where   D.ID = E.ORDER_ID   AND e.work_type_id = 1001411 )
    AND (  d.deal_oper_id IS NULL --无处理人
        OR (SELECT f_chk_idcard(x.identity_number)
                  FROM dm_staff x
                 WHERE x.id = d.deal_oper_id) = 0 --处理人身份证不合法
       ) ;


添加hints    
       /*+ use_nl(a,b) use_nl(a,c)  use_nl(c,d)  use_nl(a,dx) leading(a) */      /*+ nl_sj */      


 

1 Plan hash value: 1576200999

3 -----------------------------------------------------------------------------------------------------------------------------------
4 | Id  | Operation                                | Name                   | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
5 -----------------------------------------------------------------------------------------------------------------------------------
6 |   0 | SELECT STATEMENT                         |                        |  3537 |   449K|  1372K  (1)| 04:34:26 |       |       |
7 |*  1 |  FILTER                                  |                        |       |       |            |          |       |       |
8 |   2 |   NESTED LOOPS                           |                        | 19483 |  2473K|  1372K  (1)| 04:34:26 |       |       |
9 |   3 |    NESTED LOOPS                          |                        | 20212 |  2473K|  1372K  (1)| 04:34:26 |       |       |
10 |   4 |     NESTED LOOPS SEMI                    |                        | 20212 |  2072K|  1291K  (1)| 04:18:16 |       |       |
11 |   5 |      NESTED LOOPS                        |                        |   169K|    14M|   844K  (1)| 02:48:57 |       |       |
12 |   6 |       NESTED LOOPS                       |                        |   169K|    10M|   334K  (1)| 01:07:00 |       |       |
13 |*  7 |        TABLE ACCESS BY GLOBAL INDEX ROWID| EM_ORDER               | 98540 |  3368K| 39284   (1)| 00:07:52 |     8 |     8 |
14 |*  8 |         INDEX RANGE SCAN                 | IDX_EM_ORDER_COMP_TIME | 44669 |       |   330   (0)| 00:00:04 |       |       |
15 |*  9 |        INDEX RANGE SCAN                  | IDX_ER_ORDER_ORDER_OO  |     2 |    56 |     3   (0)| 00:00:01 |       |       |
16 |  10 |       TABLE ACCESS BY GLOBAL INDEX ROWID | EM_ORDER               |     1 |    26 |     3   (0)| 00:00:01 | ROWID | ROWID |
17 |* 11 |        INDEX UNIQUE SCAN                 | PK_EM_ORDER            |     1 |       |     2   (0)| 00:00:01 |       |       |
18 |* 12 |      TABLE ACCESS BY GLOBAL INDEX ROWID  | EE_ORDER_PF_WORK       |  1257K|    19M|     3   (0)| 00:00:01 | ROWID | ROWID |
19 |* 13 |       INDEX UNIQUE SCAN                  | PK_EE_ORDER_PF_WORK    |     1 |       |     2   (0)| 00:00:01 |       |       |
20 |* 14 |     INDEX RANGE SCAN                     | IDX_101_T_ID           |     1 |       |     3   (0)| 00:00:01 |       |       |
21 |  15 |    TABLE ACCESS BY GLOBAL INDEX ROWID    | M_101_ID_2_GID         |     1 |    25 |     4   (0)| 00:00:01 | ROWID | ROWID |
22 |  16 |   TABLE ACCESS BY INDEX ROWID            | DM_STAFF               |     1 |    20 |     3   (0)| 00:00:01 |       |       |
23 |* 17 |    INDEX UNIQUE SCAN                     | PK_DM_STAFF            |     1 |       |     2   (0)| 00:00:01 |       |       |
24 -----------------------------------------------------------------------------------------------------------------------------------
25 
26 Predicate Information (identified by operation id):
27 ---------------------------------------------------
28 
29    1 - filter("D"."DEAL_OPER_ID" IS NULL OR  (SELECT "F_CHK_IDCARD"("X"."IDENTITY_NUMBER") FROM "QWZW_ER"."DM_STAFF" "X"
30               WHERE "X"."ID"=:B1)=0)
31    7 - filter("A"."SPEC_ID"=3010200004 AND "A"."STATUS_ID"=1000007)
32    8 - access("A"."COMPLETE_TIME">=TO_DATE(' 2016-11-18 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
33               "A"."COMPLETE_TIME"<=TO_DATE(' 2016-11-18 23:59:59', 'syyyy-mm-dd hh24:mi:ss'))
34        filter(TBL$OR$IDX$PART$NUM("QWZW_ER"."EM_ORDER",0,1,0,ROWID)=8)
35    9 - access("A"."ID"="C"."A_ORDER_ID")
36   11 - access("C"."B_ORDER_ID"="D"."ID")
37   12 - filter("E"."WORK_TYPE_ID"=1001411)
38   13 - access("D"."ID"="E"."ORDER_ID")
39   14 - access("A"."ID"="B"."T_ID")
40        filter("B"."T_ID" IS NOT NULL)
41   17 - access("X"."ID"=:B1)

  
 ----  首次执行 大概在 4分钟吧,   再次执行 只需要 47S 左右。   结果大概  3千条数据。 


此致 优化结束。


另外说一句  PK_EE_ORDER_PF_WORK 索引我也压缩了一把, 因为 表4.5G,  索引3.5G, 这就是扯淡!!!   压缩后大概1G 左右。   这个其实侧面说明了数据堆积。 
规避  我想到了想到了物化视图。 1 增量情况下 我也想到了物化视图。 下面详细说明。 


后记, 这种大表, 其实我的想法是 做成 物化视图,  物化视图     ora_hash(连接字段,8)   分区  ,  EM_ORDER   做成range +  ora_hash(连接字段,8)   分区 的物化视图。
这几个表的 日增量 最大不过100M, 但是需要保存一年的数据,   commit, 提交时候   刷新物化视图,保证 无索引情况下  结果秒出.

猜你喜欢

转载自blog.csdn.net/daiqiulong2/article/details/53314003