NOT EXISTS优化

INSERT INTO F_PTY_INDIV 
  (PTY_ID,
   PTY_NAME,
   GENDER_CD,
   BIRTHDAY,
   CERT_TYPE,
   CERT_NO,
   SOCINSUR_NO,
   COUNTRY_CD,
   NATION,
   POLITICS_CD,
   MARRIAGE_STAT,
   FAMILY_ADDR,
   FAMILYZIP,
   EMAILADD,
   HOME_PHONE,
   SPU_MOBILE,
   UNITKIND,
   CUST_NAME,
   COMPANY_ADDR,
   COMPANY_TEL,
   VOCATION_CD,
   TITLE_CD,
   TOPEDU_CD,
   TOP_DEGREE_CD,
   FINANCE_OR_NOT,
   OWNBANK_FLAG,
   INPUT_ORG,
   INPUTUSERID,
   UPDATE_DATE,
   ADDRESS,
   COMMZIP,
   NATIVEADD,
   WORKZIP,
   DUTY_CD,
   WORKBEGINDATE,
   LIVESTAT_CD,
   FARMERFLAG2,
   CORP_BUS_CLASS,
   RELATIVEFLAG,
   COUNTRYCODE,
   REGION,
   CORP_ORG,
   CERT_PUT_DATE,
   CERT_END_DATE,
   SOURCE_CODE,
   START_DT,
   END_DT,
   DW_DATA_DT)
  SELECT PTY_ID,
         PTY_NAME,
         GENDER_CD,
         BIRTHDAY,
         CERT_TYPE,
         CERT_NO,
         SOCINSUR_NO,
         COUNTRY_CD,
         NATION,
         POLITICS_CD,
         MARRIAGE_STAT,
         FAMILY_ADDR,
         FAMILYZIP,
         EMAILADD,
         HOME_PHONE,
         SPU_MOBILE,
         UNITKIND,
         CUST_NAME,
         COMPANY_ADDR,
         COMPANY_TEL,
         VOCATION_CD,
         TITLE_CD,
         TOPEDU_CD,
         TOP_DEGREE_CD,
         FINANCE_OR_NOT,
         OWNBANK_FLAG,
         INPUT_ORG,
         INPUTUSERID,
         UPDATE_DATE,
         ADDRESS,
         COMMZIP,
         NATIVEADD,
         WORKZIP,
         DUTY_CD,
         WORKBEGINDATE,
         LIVESTAT_CD,
         FARMERFLAG2,
         CORP_BUS_CLASS,
         RELATIVEFLAG,
         COUNTRYCODE,
         REGION,
         CORP_ORG,
         CERT_PUT_DATE,
         CERT_END_DATE,
         SOURCE_CODE,
         START_DT,
         END_DT,
         DW_DATA_DT
    FROM F_PTY_INDIV_TMP O
   WHERE EXISTS
   (SELECT    1
            FROM F_PTY_INDIV F
           WHERE O.PTY_ID = F.PTY_ID
             AND O.CORP_ORG = F.CORP_ORG
             AND O.SOURCE_CODE = F.SOURCE_CODE)
     AND O.PTY_NAME || O.GENDER_CD || O.BIRTHDAY || O.CERT_TYPE ||
         O.CERT_NO || O.SOCINSUR_NO || O.COUNTRY_CD || O.NATION ||
         O.POLITICS_CD || O.MARRIAGE_STAT || O.FAMILY_ADDR || O.CUST_NAME ||
         O.VOCATION_CD || O.TITLE_CD || O.TOPEDU_CD || O.TOP_DEGREE_CD ||
         O.FINANCE_OR_NOT || O.OWNBANK_FLAG || O.INPUT_ORG || O.ADDRESS ||
         O.DUTY_CD || O.LIVESTAT_CD || O.FARMERFLAG2 || O.CORP_BUS_CLASS ||
         O.RELATIVEFLAG || O.COUNTRYCODE || O.REGION || O.CERT_PUT_DATE ||
         O.CERT_END_DATE NOT IN
         (SELECT  PTY_NAME || GENDER_CD || BIRTHDAY || CERT_TYPE || CERT_NO ||
                 SOCINSUR_NO || COUNTRY_CD || NATION || POLITICS_CD ||
                 MARRIAGE_STAT || FAMILY_ADDR || CUST_NAME || VOCATION_CD ||
                 TITLE_CD || TOPEDU_CD || TOP_DEGREE_CD || FINANCE_OR_NOT ||
                 OWNBANK_FLAG || INPUT_ORG || ADDRESS || DUTY_CD ||
                 LIVESTAT_CD || FARMERFLAG2 || CORP_BUS_CLASS ||
                 RELATIVEFLAG || COUNTRYCODE || REGION || CERT_PUT_DATE ||
                 CERT_END_DATE
            FROM F_PTY_INDIV
           WHERE END_DT = TO_DATE('29991231', 'YYYY-MM-DD')
             AND O.PTY_ID = PTY_ID
             AND O.CORP_ORG = CORP_ORG
             AND O.SOURCE_CODE = SOURCE_CODE) 

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

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2391619437

-------------------------------------------------------------------------------------------------
| Id  | Operation	      | Name		| Rows	| Bytes |TempSpc| Cost (%CPU)| Time	|
-------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT      | 		|     1 |   244 |	|  8587   (1)| 00:01:44 |
|*  1 |  FILTER 	      | 		|	|	|	|	     |		|
|*  2 |   HASH JOIN RIGHT SEMI| 		|     1 |   244 |    16M|  5905   (1)| 00:01:11 |
|   3 |    TABLE ACCESS FULL  | F_PTY_INDIV	|   451K|    11M|	|  2645   (1)| 00:00:32 |
|   4 |    TABLE ACCESS FULL  | F_PTY_INDIV_TMP |   131K|    27M|	|  1000   (2)| 00:00:12 |
|*  5 |   TABLE ACCESS FULL   | F_PTY_INDIV	|     1 |   142 |	|  2681   (2)| 00:00:33 |
-------------------------------------------------------------------------------------------------

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

   1 - filter( NOT EXISTS (SELECT /*+ */ 0 FROM "F_PTY_INDIV" "F_PTY_INDIV" WHERE
	      "PTY_ID"=:B1 AND "CORP_ORG"=:B2 AND "SOURCE_CODE"=:B3 AND
	      "END_DT"=TO_DATE('29991231','YYYY-MM-DD') AND
	      LNNVL(:B4||:B5||:B6||:B7||:B8||:B9||:B10||:B11||:B12||:B13||:B14||:B15||:B16||:B17||:B18|
	      |:B19||:B20||:B21||:B22||:B23||:B24||:B25||:B26||:B27||:B28||:B29||:B30||:B31||:B32<>"PTY
	      _NAME"||"GENDER_CD"||INTERNAL_FUNCTION("BIRTHDAY")||"CERT_TYPE"||"CERT_NO"||"SOCINSUR_NO"
	      ||"COUNTRY_CD"||"NATION"||"POLITICS_CD"||"MARRIAGE_STAT"||"FAMILY_ADDR"||"CUST_NAME"||"VO
	      CATION_CD"||"TITLE_CD"||"TOPEDU_CD"||"TOP_DEGREE_CD"||"FINANCE_OR_NOT"||"OWNBANK_FLAG"||"
	      INPUT_ORG"||"ADDRESS"||"DUTY_CD"||"LIVESTAT_CD"||"FARMERFLAG2"||"CORP_BUS_CLASS"||"RELATI
	      VEFLAG"||"COUNTRYCODE"||"REGION"||"CERT_PUT_DATE"||"CERT_END_DATE")))
   2 - access("O"."PTY_ID"="F"."PTY_ID" AND "O"."CORP_ORG"="F"."CORP_ORG" AND
	      "O"."SOURCE_CODE"="F"."SOURCE_CODE")
   5 - filter("PTY_ID"=:B1 AND "CORP_ORG"=:B2 AND "SOURCE_CODE"=:B3 AND
	      "END_DT"=TO_DATE('29991231','YYYY-MM-DD') AND
	      LNNVL(:B4||:B5||:B6||:B7||:B8||:B9||:B10||:B11||:B12||:B13||:B14||:B15||:B16||:B17||:B18|
	      |:B19||:B20||:B21||:B22||:B23||:B24||:B25||:B26||:B27||:B28||:B29||:B30||:B31||:B32<>"PTY
	      _NAME"||"GENDER_CD"||INTERNAL_FUNCTION("BIRTHDAY")||"CERT_TYPE"||"CERT_NO"||"SOCINSUR_NO"
	      ||"COUNTRY_CD"||"NATION"||"POLITICS_CD"||"MARRIAGE_STAT"||"FAMILY_ADDR"||"CUST_NAME"||"VO
	      CATION_CD"||"TITLE_CD"||"TOPEDU_CD"||"TOP_DEGREE_CD"||"FINANCE_OR_NOT"||"OWNBANK_FLAG"||"
	      INPUT_ORG"||"ADDRESS"||"DUTY_CD"||"LIVESTAT_CD"||"FARMERFLAG2"||"CORP_BUS_CLASS"||"RELATI
	      VEFLAG"||"COUNTRYCODE"||"REGION"||"CERT_PUT_DATE"||"CERT_END_DATE"))

37 rows selected.


改写成exists后;
 SELECT PTY_ID,
        PTY_NAME,
        GENDER_CD,
        BIRTHDAY,
        CERT_TYPE,
        CERT_NO,
        SOCINSUR_NO,
        COUNTRY_CD,
        NATION,
        POLITICS_CD,
        MARRIAGE_STAT,
        FAMILY_ADDR,
        FAMILYZIP,
        EMAILADD,
        HOME_PHONE,
        SPU_MOBILE,
        UNITKIND,
        CUST_NAME,
        COMPANY_ADDR,
        COMPANY_TEL,
        VOCATION_CD,
        TITLE_CD,
        TOPEDU_CD,
        TOP_DEGREE_CD,
        FINANCE_OR_NOT,
        OWNBANK_FLAG,
        INPUT_ORG,
        INPUTUSERID,
        UPDATE_DATE,
        ADDRESS,
        COMMZIP,
        NATIVEADD,
        WORKZIP,
        DUTY_CD,
        WORKBEGINDATE,
        LIVESTAT_CD,
        FARMERFLAG2,
        CORP_BUS_CLASS,
        RELATIVEFLAG,
        COUNTRYCODE,
        REGION,
        CORP_ORG,
        CERT_PUT_DATE,
        CERT_END_DATE,
        SOURCE_CODE,
        START_DT,
        END_DT,
        DW_DATA_DT
   FROM F_PTY_INDIV_TMP O
  WHERE EXISTS (SELECT 1
           FROM F_PTY_INDIV F
          WHERE O.PTY_ID = F.PTY_ID
            AND O.CORP_ORG = F.CORP_ORG
            AND O.SOURCE_CODE = F.SOURCE_CODE)
    AND NOT EXISTS
  (SELECT   null
           FROM F_PTY_INDIV
          WHERE O.PTY_NAME || O.GENDER_CD || O.BIRTHDAY || O.CERT_TYPE ||
                O.CERT_NO || O.SOCINSUR_NO || O.COUNTRY_CD || O.NATION ||
                O.POLITICS_CD || O.MARRIAGE_STAT || O.FAMILY_ADDR ||
                O.CUST_NAME || O.VOCATION_CD || O.TITLE_CD || O.TOPEDU_CD ||
                O.TOP_DEGREE_CD || O.FINANCE_OR_NOT || O.OWNBANK_FLAG ||
                O.INPUT_ORG || O.ADDRESS || O.DUTY_CD || O.LIVESTAT_CD ||
                O.FARMERFLAG2 || O.CORP_BUS_CLASS || O.RELATIVEFLAG ||
                O.COUNTRYCODE || O.REGION || O.CERT_PUT_DATE ||
                O.CERT_END_DATE =
                PTY_NAME || GENDER_CD || BIRTHDAY || CERT_TYPE || CERT_NO ||
                SOCINSUR_NO || COUNTRY_CD || NATION || POLITICS_CD ||
                MARRIAGE_STAT || FAMILY_ADDR || CUST_NAME || VOCATION_CD ||
                TITLE_CD || TOPEDU_CD || TOP_DEGREE_CD || FINANCE_OR_NOT ||
                OWNBANK_FLAG || INPUT_ORG || ADDRESS || DUTY_CD ||
                LIVESTAT_CD || FARMERFLAG2 || CORP_BUS_CLASS || RELATIVEFLAG ||
                COUNTRYCODE || REGION || CERT_PUT_DATE || CERT_END_DATE
            and END_DT = TO_DATE('29991231', 'YYYY-MM-DD'))
            AND O.PTY_ID = PTY_ID
            AND O.CORP_ORG = CORP_ORG
            AND O.SOURCE_CODE = SOURCE_CODE)
子查询还是无法展开


改写成关联;
SELECT o.PTY_ID,
       o.PTY_NAME,
       o.GENDER_CD,
       o.BIRTHDAY,
       o.CERT_TYPE,
       o.CERT_NO,
       o.SOCINSUR_NO,
       o.COUNTRY_CD,
       o.NATION,
       o.POLITICS_CD,
       o.MARRIAGE_STAT,
       o.FAMILY_ADDR,
       o.FAMILYZIP,
       o.EMAILADD,
       o.HOME_PHONE,
       o.SPU_MOBILE,
       o.UNITKIND,
       o.CUST_NAME,
       o.COMPANY_ADDR,
       o.COMPANY_TEL,
       o.VOCATION_CD,
       o.TITLE_CD,
       o.TOPEDU_CD,
       o.TOP_DEGREE_CD,
       o.FINANCE_OR_NOT,
       o.OWNBANK_FLAG,
       o.INPUT_ORG,
       o.INPUTUSERID,
       o.UPDATE_DATE,
       o.ADDRESS,
       o.COMMZIP,
       o.NATIVEADD,
       o.WORKZIP,
       o.DUTY_CD,
       o.WORKBEGINDATE,
       o.LIVESTAT_CD,
       o.FARMERFLAG2,
       o.CORP_BUS_CLASS,
       o.RELATIVEFLAG,
       o.COUNTRYCODE,
       o.REGION,
       o.CORP_ORG,
       o.CERT_PUT_DATE,
       o.CERT_END_DATE,
       o.SOURCE_CODE,
       o.START_DT,
       o.END_DT,
       o.DW_DATA_DT
  FROM F_PTY_INDIV_TMP O,
       (SELECT *
          FROM F_PTY_INDIV F
         WHERE END_DT = TO_DATE('29991231', 'YYYY-MM-DD')) F
 where O.PTY_ID = F.PTY_ID
   AND O.CORP_ORG = F.CORP_ORG
   AND O.SOURCE_CODE = F.SOURCE_CODE
   AND O.PTY_NAME || O.GENDER_CD || O.BIRTHDAY || O.CERT_TYPE || O.CERT_NO ||
       O.SOCINSUR_NO || O.COUNTRY_CD || O.NATION || O.POLITICS_CD ||
       O.MARRIAGE_STAT || O.FAMILY_ADDR || O.CUST_NAME || O.VOCATION_CD ||
       O.TITLE_CD || O.TOPEDU_CD || O.TOP_DEGREE_CD || O.FINANCE_OR_NOT ||
       O.OWNBANK_FLAG || O.INPUT_ORG || O.ADDRESS || O.DUTY_CD ||
       O.LIVESTAT_CD || O.FARMERFLAG2 || O.CORP_BUS_CLASS || O.RELATIVEFLAG ||
       O.COUNTRYCODE || O.REGION || O.CERT_PUT_DATE || O.CERT_END_DATE <>
       F.PTY_NAME || F.GENDER_CD || F.BIRTHDAY || F.CERT_TYPE || F.CERT_NO ||
       F.SOCINSUR_NO || F.COUNTRY_CD || F.NATION || F.POLITICS_CD ||
       F.MARRIAGE_STAT || F.FAMILY_ADDR || F.CUST_NAME || F.VOCATION_CD ||
       F.TITLE_CD || F.TOPEDU_CD || F.TOP_DEGREE_CD || F.FINANCE_OR_NOT ||
       F.OWNBANK_FLAG || F.INPUT_ORG || F.ADDRESS || F.DUTY_CD ||
       F.LIVESTAT_CD || F.FARMERFLAG2 || F.CORP_BUS_CLASS || F.RELATIVEFLAG ||
       F.COUNTRYCODE || F.REGION || F.CERT_PUT_DATE || F.CERT_END_DATE;
SQL> select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2193563055

--------------------------------------------------------------------------------------
| Id  | Operation	   | Name	     | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |		     |	  13 |	4667 |	3696   (3)| 00:00:45 |
|*  1 |  HASH JOIN	   |		     |	  13 |	4667 |	3696   (3)| 00:00:45 |
|*  2 |   TABLE ACCESS FULL| F_PTY_INDIV     |	 871 |	 120K|	2695   (3)| 00:00:33 |
|   3 |   TABLE ACCESS FULL| F_PTY_INDIV_TMP |	 131K|	  27M|	1000   (2)| 00:00:12 |
--------------------------------------------------------------------------------------

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

   1 - access("O"."PTY_ID"="F"."PTY_ID" AND "O"."CORP_ORG"="F"."CORP_ORG" AND
	      "O"."SOURCE_CODE"="F"."SOURCE_CODE")
       filter("O"."PTY_NAME"||"O"."GENDER_CD"||INTERNAL_FUNCTION("O"."BIRTHDAY
	      ")||"O"."CERT_TYPE"||"O"."CERT_NO"||"O"."SOCINSUR_NO"||"O"."COUNTRY_CD"||"O"."
	      NATION"||"O"."POLITICS_CD"||"O"."MARRIAGE_STAT"||"O"."FAMILY_ADDR"||"O"."CUST_
	      NAME"||"O"."VOCATION_CD"||"O"."TITLE_CD"||"O"."TOPEDU_CD"||"O"."TOP_DEGREE_CD"
	      ||"O"."FINANCE_OR_NOT"||"O"."OWNBANK_FLAG"||"O"."INPUT_ORG"||"O"."ADDRESS"||"O
	      "."DUTY_CD"||"O"."LIVESTAT_CD"||"O"."FARMERFLAG2"||"O"."CORP_BUS_CLASS"||"O"."
	      RELATIVEFLAG"||"O"."COUNTRYCODE"||"O"."REGION"||"O"."CERT_PUT_DATE"||"O"."CERT
	      _END_DATE"<>"F"."PTY_NAME"||"F"."GENDER_CD"||INTERNAL_FUNCTION("F"."BIRTHDAY")
	      ||"F"."CERT_TYPE"||"F"."CERT_NO"||"F"."SOCINSUR_NO"||"F"."COUNTRY_CD"||"F"."NA
	      TION"||"F"."POLITICS_CD"||"F"."MARRIAGE_STAT"||"F"."FAMILY_ADDR"||"F"."CUST_NA
	      ME"||"F"."VOCATION_CD"||"F"."TITLE_CD"||"F"."TOPEDU_CD"||"F"."TOP_DEGREE_CD"||
	      "F"."FINANCE_OR_NOT"||"F"."OWNBANK_FLAG"||"F"."INPUT_ORG"||"F"."ADDRESS"||"F".
	      "DUTY_CD"||"F"."LIVESTAT_CD"||"F"."FARMERFLAG2"||"F"."CORP_BUS_CLASS"||"F"."RE
	      LATIVEFLAG"||"F"."COUNTRYCODE"||"F"."REGION"||"F"."CERT_PUT_DATE"||"F"."CERT_E
	      ND_DATE")
   2 - filter("END_DT"=TO_DATE('29991231','YYYY-MM-DD'))

32 rows selected.

优化到此结束。

原文地址:https://www.cnblogs.com/zhaoyangjian724/p/3797961.html