HelloDBA [中文]
Search Internet Search HelloDBA
  Oracle Technology Site. email: fuyuncat@gmail.com  MSN: fuyuncat@hotmail.com Add to circle  acoug  acoug 

NULL IS NOT NULL in execution plan

[中文]

Author:  fuyuncat

Source:  www.HelloDBA.com

Date:  2010-03-04 03:09:52

Share to  Twitter Facebook GMail Blogger Orkut Google Bookmarks Sina Weibo QQ Renren Tieba Kaixin Douban Taobao

    I get a SQL from a developer today, he was confused by its execution plan output.
 

SQL代码
  1. HELLODBA.COM> explain plan for  
  2.   2  SELECT MAX(CNTR_MVMT_ID)   
  3.   3                         FROM CS2_CT_MVMT MVMT   
  4.   4                        WHERE MVMT.CNTR_NUM = :P_CNTR_NUM   
  5.   5                          AND MVMT.SP_COMPANY_ID = :P_SVC_PRD_ID   
  6.   6                          AND NVL(MVMT.EVENT_CURRENT_CONTRA_IND,'0')='DELETED'  
  7.   7                          AND NVL(MVMT.EVENT_CURRENT_CONTRA_IND,'0')= 'ROLLBACK'  
  8.   8                           AND exists   
  9.   9                           (select 1 from standard_event_label s where s.event_code= mvmt.event_cs_cde   
  10.  10                            and nvl(s.dimension_type, '0')= nvl(mvmt.event_cs_dimension_tp,'0')   
  11.  11                            and nvl(mvmt.event_cs_dimension_vl,'0')=nvl(s.dimension_value,'0')   
  12.  12                            and mvmt.event_cs_est_actual_ind= s.est_actual_indicator   
  13.  13                            and s.is_display='1')   
  14.  14                            and exists(select 1 from cs2_ct_bl_info ctbl where ctbl.cntr_mvmt_id=mvmt.cntr_mvmt_id   
  15.  15                            and ctbl.bl_num='NGBLAX021099');   
  16.   
  17. Explained.   
  18.   
  19. SQL> select * from table(dbms_xplan.display());   
  20.   
  21. PLAN_TABLE_OUTPUT   
  22. ---------------------------------------------------------------------------------------------------------------------   
  23. Plan hash value: 2642346965   
  24.   
  25. --------------------------------------------------------------------------------------------------------------   
  26. | Id  | Operation                         | Name                     | Rows  | Bytes | Cost (%CPU)| Time     |   
  27. --------------------------------------------------------------------------------------------------------------   
  28. |   0 | SELECT STATEMENT                  |                          |     1 |   156 |     0   (0)|       |   
  29. |   1 |  SORT AGGREGATE                   |                          |     1 |   156 |            |       |   
  30. |*  2 |   FILTER                          |                          |       |       |            |       |   
  31. |*  3 |    HASH JOIN SEMI                 |                          |     1 |   156 |   100   (2)| 00:00:02 |   
  32. |*  4 |     TABLE ACCESS BY INDEX ROWID   | CS2_CT_MVMT              |     1 |   109 |     2   (0)| 00:00:01 |   
  33. |   5 |      NESTED LOOPS                 |                          |    35 |  4445 |    97   (2)| 00:00:02 |   
  34. |   6 |       SORT UNIQUE                 |                          |    63 |  1134 |    63   (0)| 00:00:01 |   
  35. |   7 |        TABLE ACCESS BY INDEX ROWID| CS2_CT_BL_INFO           |    63 |  1134 |    63   (0)| 00:00:01 |   
  36. |*  8 |         INDEX RANGE SCAN          | CS2_CT_BL_INFO_IDX2      |    63 |       |     4   (0)| 00:00:01 |   
  37. |*  9 |       INDEX RANGE SCAN            | CS2_CT_MVMT_PK1          |     1 |       |     1   (0)| 00:00:01 |   
  38. |* 10 |     TABLE ACCESS BY INDEX ROWID   | STANDARD_EVENT_LABEL     |    48 |  1392 |     2   (0)| 00:00:01 |   
  39. |* 11 |      INDEX FULL SCAN              | STANDARD_EVENT_LABEL_UK1 |    55 |       |     1   (0)| 00:00:01 |   
  40. --------------------------------------------------------------------------------------------------------------   
  41.   
  42. Predicate Information (identified by operation id):   
  43. ---------------------------------------------------   
  44.   
  45.    2 - filter(NULL IS NOT NULL)   
  46.    3 - access("S"."EVENT_CODE"="MVMT"."EVENT_CS_CDE" AND  
  47.               NVL("S"."DIMENSION_TYPE",'0')=NVL("MVMT"."EVENT_CS_DIMENSION_TP",'0'AND  
  48.               NVL("MVMT"."EVENT_CS_DIMENSION_VL",'0')=NVL("S"."DIMENSION_VALUE",'0'AND  
  49.               "MVMT"."EVENT_CS_EST_ACTUAL_IND"="S"."EST_ACTUAL_INDICATOR")   
  50.    4 - filter("MVMT"."CNTR_NUM"=:P_CNTR_NUM AND "MVMT"."SP_COMPANY_ID"=:P_SVC_PRD_ID AND  
  51.               ("MVMT"."EVENT_CS_EST_ACTUAL_IND"='A' OR "MVMT"."EVENT_CS_EST_ACTUAL_IND"='E' OR  
  52.               "MVMT"."EVENT_CS_EST_ACTUAL_IND"='N'AND NVL("MVMT"."EVENT_CURRENT_CONTRA_IND",'0')='DELETED')   
  53.    8 - access("CTBL"."BL_NUM"='NGBLAX021099')   
  54.    9 - access("CTBL"."CNTR_MVMT_ID"="MVMT"."CNTR_MVMT_ID")   
  55.   10 - filter("S"."IS_DISPLAY"=1)   
  56.   11 - filter("S"."EST_ACTUAL_INDICATOR" IS NOT NULL)   

    He was confused by the cost of the plan. Eventhough the cost of the sub plan tree is 100, the final cost is 0.
 

    Look into the output, the 2nd filter in the predicate information, NULL IS NOT NULL. It's added by the optimizer automaticly. We know NULL IS NOT NULL is means always FALSE. Optimzier will add such filter when it found the logic result of the sub plan tree is FALSE, it will cause to the plan tree will never be executed. So, no matter how much cost of the plan tree, it will become 0 with this filter.
 

    When find such filter added by optimizer, it's normally means a logic problem in the SQL. Review the SQL, we can find the logic defect quickly:
 

SQL代码
  1. 6                          AND NVL(MVMT.EVENT_CURRENT_CONTRA_IND,'0')='DELETED'  
  2. 7                          AND NVL(MVMT.EVENT_CURRENT_CONTRA_IND,'0')= 'ROLLBACK'  

    This means 'DELETED'='ROLLBACK', impossible. Double check with the developer, it's his typo. The "=" should be "!=".
 

    --- Fuyuncat ---

Top

Copyright ©2005, HelloDBA.Com All reseverd.

Declaration
by fuyuncat