Skip to Main Content

Oracle Database Discussions

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

CBO not picking the right execution plan

joshicOct 6 2008 — edited Oct 28 2008
Database: Oracle 9.2.0.6 EE
OS:Solaris 9

I am trying to tune a query that is generated via Siebel Analytics. I am seeing a behaviour which is puzzling me but hopefully would be 'elementary' for someone like JPL.

The query is based on a total of 7 tables. If I comment out any 2 dimension tables, the query picks up the right index on the fact table. However, the moment I add another table to the query, the plan goes awry.

The query with 5 tables is as below:
select count(distinct decode( T30256.HEADER_FLG , 'N' , T30256.ROW_WID ) ) as c1,
T352305.DAY_DT as c2,
case  when T44643.PRODUCT_CLASS_NAME = 'MobileSubscription' then T40081.ATTR15_CHAR_VAL else 'Unspecified' end  as c3,
T352305.ROW_WID as c5
from 
               W_PRODUCT_D T30955,
               W_PRDATTRNM_D T44643,                          
               W_DAY_D T352305,                  
               W_ORDERITEM_F T30256,               
               W_PRDATTR_D T40081                          
where  ( T30955.ROW_WID = T44643.ROW_WID 
and T30256.LAST_UPD_DT_WID = T352305.ROW_WID 
and T30256.PROD_ATTRIB_WID = T40081.ROW_WID  
and T30256.PROD_WID = T30955.ROW_WID 
and T30955.PROD_NAME = 'Mobile Subscription' 
and (case  when T44643.PRODUCT_CLASS_NAME = 'MobileSubscription' then T40081.ATTR15_CHAR_VAL else 'Unspecified' end  in ('BT150BB-18M', 'BT250BB-18M', 'BT50BB-18M', 'BT600BB-18M')) 
and T352305.DAY_DT between TO_DATE('2008-09-27' , 'YYYY-MM-DD') - 7 and TO_DATE('2008-09-27' , 'YYYY-MM-DD') - 1 
) 
group by 
T352305.ROW_WID, T352305.DAY_DT, 
case  when T44643.PRODUCT_CLASS_NAME = 'MobileSubscription' then T40081.ATTR15_CHAR_VAL else 'Unspecified' end 
;
And the execution plan is as below:
----------------------------------------------------------------------------------------------
| Id  | Operation                        |  Name                | Rows  | Bytes | Cost (%CPU)|
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |                      |   269 | 25824 | 18660   (3)|
|   1 |  SORT GROUP BY                   |                      |   269 | 25824 | 18660   (3)|
|   2 |   NESTED LOOPS                   |                      |   269 | 25824 | 18658   (3)|
|   3 |    NESTED LOOPS                  |                      |  6826 |   579K|  4734   (3)|
|   4 |     MERGE JOIN CARTESIAN         |                      |     8 |   544 |     6  (17)|
|   5 |      NESTED LOOPS                |                      |     1 |    54 |     4  (25)|
|   6 |       TABLE ACCESS BY INDEX ROWID| W_PRODUCT_D          |     1 |    37 |     3  (34)|
|*  7 |        INDEX RANGE SCAN          | W_PRODUCT_D_M2       |     1 |       |     2  (50)|
|   8 |       TABLE ACCESS BY INDEX ROWID| W_PRDATTRNM_D        |     1 |    17 |     2  (50)|
|*  9 |        INDEX UNIQUE SCAN         | W_PRDATTRNM_D_P1     |     1 |       |            |
|  10 |      BUFFER SORT                 |                      |     8 |   112 |     4   (0)|
|  11 |       TABLE ACCESS BY INDEX ROWID| W_DAY_D              |     8 |   112 |     3  (34)|
|* 12 |        INDEX RANGE SCAN          | W_DAY_D_M39          |     8 |       |     2  (50)|
|  13 |     TABLE ACCESS BY INDEX ROWID  | W_ORDERITEM_F        |   849 | 16131 |   592   (3)|
|* 14 |      INDEX RANGE SCAN            | W_ORDERITEM_F_INDX9  |   852 |       |     4  (25)|
|* 15 |    INDEX RANGE SCAN              | W_PRDATTR_D_M29_T1   |     1 |     9 |     3  (34)|
----------------------------------------------------------------------------------------------
Note how the dimension tables W_PRODUCT_D & W_DAY_D are joined using cartesian join before joining to the fact table W_ORDERITEM_F using the composite index 'W_ORDERITEM_F_INDX9'. This index consists of LAST_UPD_DT_WID, PROD_WID and ACTION_TYPE_WID, which are foreign keys to the dimension tables.

Now if I add one more table to the query:
select count(distinct decode( T30256.HEADER_FLG , 'N' , T30256.ROW_WID ) ) as c1,
              T352305.DAY_DT as c2,
               case  when T44643.PRODUCT_CLASS_NAME = 'MobileSubscription' then T40081.ATTR15_CHAR_VAL else 'Unspecified' end  as c3,
               T30371.X_BT_DLR_GROUP as c4,
               T352305.ROW_WID as c5
          from                W_PRODUCT_D T30955,
               W_PRDATTRNM_D T44643,                          
               W_DAY_D T352305,                  
               W_ORDERITEM_F T30256,               
               W_ORDER_D T30371,                                             
               W_PRDATTR_D T40081                          
          where  ( T30955.ROW_WID = T44643.ROW_WID 
          and T30256.LAST_UPD_DT_WID = T352305.ROW_WID 
          and T30256.PROD_ATTRIB_WID = T40081.ROW_WID 
          and T30256.PROD_WID = T30955.ROW_WID 
          and T30256.ORDER_WID = T30371.ROW_WID 
          and T30955.PROD_NAME = 'Mobile Subscription' 
          and T30371.STATUS_CD = 'Complete' 
          and T30371.ORDER_TYPE = 'Sales Order'  
          and (case  when T44643.PRODUCT_CLASS_NAME = 'MobileSubscription' then T40081.ATTR15_CHAR_VAL else 'Unspecified' end  in ('BT150BB-18M', 'BT250BB-18M', 'BT50BB-18M', 'BT600BB-18M')) 
          and T352305.DAY_DT between TO_DATE('2008-09-27' , 'YYYY-MM-DD') - 7 and TO_DATE('2008-09-27' , 'YYYY-MM-DD') - 1 
         ) 
          group by T30371.X_BT_DLR_GROUP, T352305.ROW_WID, T352305.DAY_DT, 
          case  when T44643.PRODUCT_CLASS_NAME = 'MobileSubscription' then T40081.ATTR15_CHAR_VAL else 'Unspecified' end;
I have added a single table W_ORDER_D to the query, and the execution plan is:
-----------------------------------------------------------------------------------------------
| Id  | Operation                          |  Name               | Rows  | Bytes | Cost (%CPU)|
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                   |                     |    44 |  6336 | 78695   (3)|
|   1 |  SORT GROUP BY                     |                     |    44 |  6336 | 78695   (3)|
|   2 |   NESTED LOOPS                     |                     |    44 |  6336 | 78694   (3)|
|   3 |    NESTED LOOPS                    |                     |   269 | 27707 | 78145   (3)|
|*  4 |     HASH JOIN                      |                     |  6826 |   626K| 64221   (3)|
|   5 |      TABLE ACCESS BY INDEX ROWID   | W_DAY_D             |     8 |   112 |     4  (25)|
|*  6 |       INDEX RANGE SCAN             | W_DAY_D_M39         |     1 |       |     3  (34)|
|   7 |      TABLE ACCESS BY INDEX ROWID   | W_ORDERITEM_F       | 86886 |  2206K| 64197   (3)|
|   8 |       NESTED LOOPS                 |                     | 87004 |  6797K| 64200   (3)|
|   9 |        NESTED LOOPS                |                     |     1 |    54 |     4  (25)|
|  10 |         TABLE ACCESS BY INDEX ROWID| W_PRODUCT_D         |     1 |    37 |     3  (34)|
|* 11 |          INDEX RANGE SCAN          | W_PRODUCT_D_M2      |     1 |       |     2  (50)|
|  12 |         TABLE ACCESS BY INDEX ROWID| W_PRDATTRNM_D       |     1 |    17 |     2  (50)|
|* 13 |          INDEX UNIQUE SCAN         | W_PRDATTRNM_D_P1    |     1 |       |            |
|* 14 |        INDEX RANGE SCAN            | W_ORDERITEM_F_N6    | 86886 |       |   212  (18)|
|* 15 |     INDEX RANGE SCAN               | W_PRDATTR_D_M29_T1  |     1 |     9 |     3  (34)|
|* 16 |    INDEX RANGE SCAN                | W_ORDER_D_N6        |     1 |    41 |     3  (34)|
-----------------------------------------------------------------------------------------------
Now CBO doesn't choose the composite index and the cost also has increased to 78695. But if I simply add an /*+ORDERED*/ hint to the above query, so that it should join the dimension tables before joining to fact table, then the cost drops to 20913. This means that CBO is not choosing the plan with the lowest cost. I tried increasing the optimizer_max_permutations to 80000, setting session level optimizer_dynamic_sampling to 8 (just to see if it works), but no success.

Could you please advise how to overcome this problem?

Many thanks.
This post has been answered by Randolf Geist on Oct 7 2008
Jump to Answer
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Nov 25 2008
Added on Oct 6 2008
29 comments
1,562 views