您的位置:首页 > 其它

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

2016-11-23 23:35 106 查看


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, 提交时候   刷新物化视图,保证 无索引情况下  结果秒出.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: