子查询解嵌套not in 无法展开改写

SQL> explain plan for select *

  from OPS$CZTEST1.SAVJ_ATOMJOURBAK

 where ((list_flag = '1' and prt_flag = '0') and

       acct_no not in

       (select acct_no

           from OPS$CZTEST1.savb_basicinfo1

          where ((card_no is not null and base_acct_no is null) or

                (book_flag = '1' and bus_code = 21))));  2    3    4    5    6    7    8 



Explained.



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



PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Plan hash value: 3909253513



--------------------------------------------------------------------------------------

| Id  | Operation                             | Name                         | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT      |                                       | 54953 |    18M|   594M  (1)      |999:59:59 |

|*  1 |  FILTER                               |                                       |             |            |                           |          |

|*  2 |   TABLE ACCESS FULL   | SAVJ_ATOMJOUR0  | 54954 |    18M|  1042   (3)       | 00:00:13 |

|*  3 |   TABLE ACCESS FULL  | SAVB_BASICINFO1   |     1       |    73   | 11220   (1)     | 00:02:15 |

--------------------------------------------------------------------------------------



Predicate Information (identified by operation id):

---------------------------------------------------



   1 - filter( NOT EXISTS (SELECT /*+ */ 0 FROM

              "OPS$CZTEST1"."SAVB_BASICINFO1" "SAVB_BASICINFO1" WHERE ("BASE_ACCT_NO" IS

              NULL AND "CARD_NO" IS NOT NULL OR "BUS_CODE"=21 AND "BOOK_FLAG"='1') AND

              LNNVL("ACCT_NO"<>:B1)))

   2 - filter("PRT_FLAG"='0' AND "LIST_FLAG"='1')

   3 - filter(("BASE_ACCT_NO" IS NULL AND "CARD_NO" IS NOT NULL OR

              "BUS_CODE"=21 AND "BOOK_FLAG"='1') AND LNNVL("ACCT_NO"<>:B1))



21 rows selected.





可以看到这里:

( NOT EXISTS (SELECT /*+ */ 0 FROM

              "OPS$CZTEST1"."SAVB_BASICINFO1" "SAVB_BASICINFO1" WHERE ("BASE_ACCT_NO" IS

              NULL AND "CARD_NO" IS NOT NULL OR "BUS_CODE"=21 AND "BOOK_FLAG"='1') AND

              LNNVL("ACCT_NO"<>:B1)))



子查询没有展开,FILTER 循环类似于NL循环,会导致表SAVB_BASICINFO1访问多次,not in 可以改写成左关联的形式,改写如下:

SQL> explain plan for select count(*)

  from OPS$CZTEST1.SAVJ_ATOMJOURBAK a,

       (select acct_no

          from OPS$CZTEST1.savb_basicinfo1

         where (card_no is not null and base_acct_no is null)

        or

          (book_flag = '1' and bus_code = 21)) b

 where a.list_flag = '1'

   and a.prt_flag = '0'

   and a.acct_no = b.acct_no(+)

   and b.acct_no is null;  2    3    4    5    6    7    8    9   10   11  



Explained.



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



PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Plan hash value: 4182698075



-----------------------------------------------------------------------------------------------

| Id  | Operation                           | Name                          | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |

-----------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT     |                                       |     1      |   110 |       | 13060   (1)| 00:02:37 |

|   1 |  SORT AGGREGATE        |                                      |     1       |   110 |       |            |          |

|*  2 |   HASH JOIN ANTI            |                                     |             1 |   110 |  2632K| 13060   (1)| 00:02:37 |

|*  3 |    TABLE ACCESS FULL | SAVJ_ATOMJOUR0  | 54954 |  1985K|       |  1041   (2)| 00:00:13 |

|*  4 |    TABLE ACCESS FULL | SAVB_BASICINFO1 |   166K|    11M|       | 11216   (1)| 00:02:15 |

-----------------------------------------------------------------------------------------------



Predicate Information (identified by operation id):

---------------------------------------------------



   2 - access("ACCT_NO"="ACCT_NO")

   3 - filter("PRT_FLAG"='0' AND "LIST_FLAG"='1')

   4 - filter("BASE_ACCT_NO" IS NULL AND "CARD_NO" IS NOT NULL OR "BUS_CODE"=21 AND

              "BOOK_FLAG"='1')



19 rows selected.



 



 



 


 

你可能感兴趣的:(not in)