Tuesday, June 03, 2008

Execution plan does not match between explain time and execution time

Some time ago, I have observed that some sqls used bad execution plan during run time, which are different from the execution plan that we obtained by autotrace or explain plan statement. Here is an example (the environment: 9.2.0.8):

The sql is as follows: (changed the table name for hiding confidential information)


select 'Pots,',count(distinct(od.master_order_id))
from tableOD od,
tableSD sd
where
sd.MASTER_ORDER_ID=od.MASTER_ORDER_ID
and sd.SUB_ORDER_TYPE in (1,3,4)
and sd.product_category in (2,3,17)
and sd.SUPP_ORDER_ID=0
and sd.service_type='Install'
and od.RECEIVED_DATE between To_Date('05/20/08 00:00:00','MM/DD/YY HH24:MI:SS')
and To_Date('05/20/08 23:59:59','MM/DD/YY HH24:MI:SS')
and (sd.SSPUNITY in ('N') or sd.SSPUNITY is null )
and (sd.DRY_LOOP_IND in ('N') or sd.DRY_LOOP_IND is null )
and (sd.HARMONY_DATA_RECEIVED = 'N' or sd.HARMONY_DATA_RECEIVED is null )
group by trunc(od.RECEIVED_DATE),sd.SSPUNITY,sd.HARMONY_DATA_RECEIVED,sd.DRY_LOOP_IND;





The explain plan obtained from explain plan statment is:


-------------------------------------------------------------------------------------------------
Id Operation Name Rows Bytes Cost (%CPU)
-------------------------------------------------------------------------------------------------
0 SELECT STATEMENT 2 122 14 (15)
1 SORT GROUP BY 2 122 14 (15)
* 2 FILTER
* 3 TABLE ACCESS BY INDEX ROWID TABLESD 1 38 5 (20)
4 NESTED LOOPS 2 122 13 (8)
5 TABLE ACCESS BY INDEX ROWID TABLEOD 2 46 5 (20)
* 6 INDEX RANGE SCAN ORD_DTL_RECV_DATE 2 4 (25)
* 7 INDEX RANGE SCAN SSD_MASTER_ORDER_ID_NUK 1 4 (25)
-------------------------------------------------------------------------------------------------


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

2 - filter(TO_DATE('05/20/08 00:00:00','MM/DD/YY HH24:MI:SS')<=TO_DATE('05/20/08 23:59:59','MM/DD/YY HH24:MI:SS')) 3 - filter("TABLESD"."SERVICE_TYPE"='Install' AND ("TABLESD"."DRY_LOOP_IND"='N' OR "TABLESD"."DRY_LOOP_IND" IS N ULL) AND ("TABLESD"."HARMONY_DATA_RECEIVED" IS NULL OR "TABLESD"."HARMONY_DATA_RECEIVED"='N') AND TO_NUMBER("TABLESD"."SUPP_ORDER_ID")=0 AND ("TABLESD"."PRODUCT_CATEGORY"=2 OR "TABLESD"."PRODUCT_CATEGORY "=3 OR "TABLESD"."PRODUCT_CATEGORY"=17) AND ("TABLESD"."SSPUNITY" IS NULL OR "TABLESD"."SSPUNITY"='N') AND (TO_NUMBER("TABLESD"."SUB_ORDER_TYPE")=1 OR TO_NUMBER("TABLESD"."SUB_ORDER_TYPE")=3 OR TO_NUMBER("TABLESD"."SUB_ORDER_TYPE")=4)) 6 - access("TABLEOD"."RECEIVED_DATE">=TO_DATE('05/20/08 00:00:00','MM/DD/YY
HH24:MI:SS') AND "TABLEOD"."RECEIVED_DATE"<=TO_DATE('05/20/08 23:59:59','MM/DD/YY HH24:MI:SS')) 7 - access("TABLESD"."MASTER_ORDER_ID"="TABLEOD"."MASTER_ORDER_ID") 33 rows selected.




However, during execution time, the execution plan obtained from v$sql_plan is:



--------------------------------------------------------------------------------------------
Id Operation Name Rows Bytes Cost (%CPU)
--------------------------------------------------------------------------------------------
0 SELECT STATEMENT
1 SORT GROUP BY 1042 63562 420K (6)
2 FILTER
3 NESTED LOOPS 1042 63562 420K (6)
4 TABLE ACCESS FULL TABLESD 1042 39596 416K (6)
5 TABLE ACCESS BY INDEX ROWID TABLEOD 1 23 5 (20)
6 INDEX RANGE SCAN TEMP_1 1 4 (25)
--------------------------------------------------------------------------------------------

No comments: