一个笛卡尔积的优化

原SQL:业务需求需要开发一张表,但是发现执行很慢,我就看了执行计划,
MERGE JOIN CARTESIAN发生笛卡尔积,4dp这张表和6cp这张表发生笛卡尔积,生成的结果集3和8mp又发生一次结果集,也就是说
本身没有关系的表发生了笛卡尔积。这里需要声明几点,cp这张表数据将近50万,mp有将近80万的数据,dp也就不到10条数据
mt表有150万数据量


select   
 null      BAIHUI_ID,
       TRANSQ,
       DETLSQ,
       ACCTNO,
       mp.member_cd CUSTAC,
       TRANDT    TRASDT,
       TRANAM,
       TRANTM    TRASTM,
       avalbl  AVALBL, 
       SERVTP CHNLNO,
       dp.name CNOVAL,
       decode(AMNTCD, 'C', '转入', 'D', '转出') FLOWTP,
       INTRCD,
       class1,
       TRANST,
       decode(mt.transt,'1','成功','0','失败')TRTVAL,
       greatest(sysdate) UPDATETIME,
       cp.CUSTAC MEBECD,
       MERCNO
  from ods_member_trans mt
 inner join dim_client_tp dp
    on (mt.servtp = dp.id)
inner join ods_member_mapping mp
on(mt.member_cd=mp.mapping_cd)
inner join ods_custac_mapping cp
on(cp.mapping_cd=mt.custac);
 SQL> select * from table(dbms_xplan.display);


PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------------
Plan hash value: 4130571362


---------------------------------------------------------------------------------------------
| Id  | Operation              | Name               | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |                    |     1 |   378 | 13937   (1)| 00:02:48 |
|*  1 |  HASH JOIN             |                    |     1 |   378 | 13937   (1)| 00:02:48 |
|   2 |   MERGE JOIN CARTESIAN |                    |   363 | 76593 |  2603   (1)| 00:00:32 |
|   3 |    MERGE JOIN CARTESIAN|                    |     1 |   158 |   892   (1)| 00:00:11 |
|   4 |     TABLE ACCESS FULL  | DIM_CLIENT_TP      |     1 |   114 |     2   (0)| 00:00:01 |
|   5 |     BUFFER SORT        |                    |   468K|    19M|   890   (1)| 00:00:11 |
|   6 |      TABLE ACCESS FULL | ODS_CUSTAC_MAPPING |   468K|    19M|   890   (1)| 00:00:11 |
|   7 |    BUFFER SORT         |                    |   774K|    39M|  1713   (1)| 00:00:21 |
|   8 |     TABLE ACCESS FULL  | ODS_MEMBER_MAPPING |   774K|    39M|  1711   (1)| 00:00:21 |
|   9 |   TABLE ACCESS FULL    | ODS_MEMBER_TRANS   |  1487K|   236M| 11330   (1)| 00:02:16 |
---------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------


   1 - access("CP"."MAPPING_CD"="MT"."CUSTAC" AND "MT"."MEMBER_CD"="MP"."MAPPING_CD"
              AND "MT"."SERVTP"="DP"."ID")


已选择22行。
我使用了hint关闭这个笛卡尔积以后,发现还是很慢查看执行计划, 走了NL,执行计划如下




SQL>
SQL>  explain plan for
  2  select /*+ OPT_PARAM('_optimizer_mjc_enabled','false') */null      BAIHUI_ID,
  3         TRANSQ,
  4         DETLSQ,
  5         ACCTNO,
  6         mp.member_cd CUSTAC,
  7         TRANDT    TRASDT,
  8         TRANAM,
  9         TRANTM    TRASTM,
 10         avalbl  AVALBL,
 11         SERVTP CHNLNO,
 12         dp.name CNOVAL,
 13         decode(AMNTCD, 'C', '转入', 'D', '转出') FLOWTP,
 14         INTRCD,
 15         class1,
 16         TRANST,
 17         decode(mt.transt,'1','成功','0','失败')TRTVAL,
 18         greatest(sysdate) UPDATETIME,
 19         cp.CUSTAC MEBECD,
 20         MERCNO
 21    from ods_member_trans mt
 22   inner join dim_client_tp dp
 23      on (mt.servtp = dp.id)
 24  inner join ods_member_mapping mp
 25  on(mt.member_cd=mp.mapping_cd)
 26  inner join ods_custac_mapping cp
 27  on(cp.mapping_cd=mt.custac);


已解释。


SQL> select * from table(dbms_xplan.display);


PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------
Plan hash value: 3453093643


-------------------------------------------------------------------------------------------
| Id  | Operation            | Name               | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                    |     1 |   378 | 13937   (1)| 00:02:48 |
|*  1 |  HASH JOIN           |                    |     1 |   378 | 13937   (1)| 00:02:48 |
|   2 |   NESTED LOOPS       |                    |   363 | 76593 |  2603   (1)| 00:00:32 |
|   3 |    NESTED LOOPS      |                    |     1 |   158 |   892   (1)| 00:00:11 |
|   4 |     TABLE ACCESS FULL| DIM_CLIENT_TP      |     1 |   114 |     2   (0)| 00:00:01 |
|   5 |     TABLE ACCESS FULL| ODS_CUSTAC_MAPPING |   468K|    19M|   890   (1)| 00:00:11 |
|   6 |    TABLE ACCESS FULL | ODS_MEMBER_MAPPING |   774K|    39M|  1711   (1)| 00:00:21 |
|   7 |   TABLE ACCESS FULL  | ODS_MEMBER_TRANS   |  1487K|   236M| 11330   (1)| 00:02:16 |
-------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------


   1 - access("CP"."MAPPING_CD"="MT"."CUSTAC" AND
              "MT"."MEMBER_CD"="MP"."MAPPING_CD" AND "MT"."SERVTP"="DP"."ID")


已选择20行。


最后我使用了HASH和NL的hint来进行优化,由于dp这张表就不到10条数据,所以选择NL的方式,最后12秒数据就执行出来了


SQL> select * from table(dbms_xplan.display);


PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------
Plan hash value: 2582556817


-------------------------------------------------------------------------------------------
| Id  | Operation            | Name               | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                    |     1 |   378 | 13936   (1)| 00:02:48 |
|*  1 |  HASH JOIN           |                    |     1 |   378 | 13936   (1)| 00:02:48 |
|*  2 |   HASH JOIN          |                    |     1 |   325 | 12223   (1)| 00:02:27 |
|   3 |    NESTED LOOPS      |                    |     1 |   281 | 11332   (1)| 00:02:16 |
|   4 |     TABLE ACCESS FULL| DIM_CLIENT_TP      |     1 |   114 |     2   (0)| 00:00:01 |
|*  5 |     TABLE ACCESS FULL| ODS_MEMBER_TRANS   |     1 |   167 | 11330   (1)| 00:02:16 |
|   6 |    TABLE ACCESS FULL | ODS_CUSTAC_MAPPING |   468K|    19M|   890   (1)| 00:00:11 |
|   7 |   TABLE ACCESS FULL  | ODS_MEMBER_MAPPING |   774K|    39M|  1711   (1)| 00:00:21 |
-------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------


   1 - access("MT"."MEMBER_CD"="MP"."MAPPING_CD")
   2 - access("CP"."MAPPING_CD"="MT"."CUSTAC")
   5 - filter("MT"."SERVTP"="DP"."ID")


已选择21行。


你可能感兴趣的:(SQL,Tuning)