Java Mailing List Archive

http://www.dba.5341.com/

Home » Home (12/2007) » oracle l »

Why is the full table scan not being chosen?

Stuart Clowes

2006-07-05

Replies:

Now, I'm not desperately experienced at reading 10053 trace files, and I'm wading through Jonathan Lewis' CBO book, so a  'RTFM' reply wouldn't be unwarranted (provided somebody points me to which part of  TFM I should R).
 
 
 
 
We have a table IMMD_NEEDS, PK on (WHSE, IMMD_NEED_ID). Table has 31407 rows. The WHSE column is skewed: two distinct values with 3 and 31404 rows. Histogram reflects this.
8K block size
DBFMRC=8. OPTIMIZER_MODE=FIRST_ROWS.
 
I'm having problems understanding why the optimizer not picking a full table scan access path for a particular query:
 

explain plan for
SELECT /*+FULL(IMMD_NEEDS)*/ IMMD_NEEDS.WHSE, IMMD_NEEDS.IMMD_NEED_ID, IMMD_NEEDS.SHPMT_NBR, IMMD_NEEDS.CASE_NBR, IMMD_NEEDS.PO_NBR, IMMD_NEEDS.SKU_ID
, IMMD_NEEDS.INVN_TYPE, IMMD_NEEDS.PROD_STAT, IMMD_NEEDS.BATCH_NBR, IMMD_NEEDS.SKU_ATTR_1, IMMD_NEEDS.SKU_ATTR_2, IMMD_NEEDS.SKU_ATTR_3, IMMD_NEEDS.SKU_ATTR_4, IMMD_NEEDS.SKU_ATTR_5, IMMD_NEEDS.CNTRY_OF_ORGN, IMMD_NEEDS.IMMD_NEED_PRTY, IMMD_NEEDS.REC_TYPE, IMMD_NEEDS.TMPL_ID, IMMD_NEEDS.SNGL_CASE_REQD, IMMD_NEEDS.PCNT_XCESS_NEED, IMMD_NEEDS.PERM_NEED_FLAG, IMMD_NEEDS.SNGL_SKU_CASE,
 IMMD_NEEDS.CASE_PROC, IMMD_NEEDS.IMMD_NEED_TYPE, IMMD_NEEDS.PUTWY_TYPE, IMMD_NEEDS.QTY_TYPE, IMMD_NEEDS.QTY_REQD, IMMD_NEEDS.QTY_FULFLD, IMMD_NEEDS.CMNT, IMMD_NEEDS.STAT_CODE, IMMD_NEEDS.SRC_OF_NEED, IMMD_NEEDS.CREATE_DATE_TIME, IMMD_NEEDS.MOD_DATE_TIME,
IMMD_NEEDS.USER_ID, IMMD_NEEDS.STAT_CODE_UPDATE, IMMD_NEEDS.REMOVE_LOCK_FLAG, IMMD_NEEDS.REMOVE_LOCK_DTL_FLAG, IMMD_NEEDS.RELEASE_DTL_FLAG, IMMD_NEEDS.ORIG_WHSE, IMMD_NEEDS.ORIG_IMMD_NEED_ID FROM IMMD_NEEDS WHERE ( ( ( ( ( ( IMMD_NEEDS.WHSE = :1 ) AND ( IMMD_NEEDS.SHPMT_NBR = :2 ) ) AND ( IMMD_NEEDS.SKU_ID = :3 ) ) AND ( IMMD_NEEDS.STAT_CODE = :4 ) ) AND ( ( IMMD_NEEDS.CASE_NBR = :5 ) OR ( IMMD_NEEDS.CASE_NBR IS NULL ) ) ) AND ( ( IMMD_NEEDS.PO_NBR = :6 ) OR ( IMMD_NEEDS.PO_NBR IS NULL ) ) ) ORDER BY IMMD_NEEDS.IMMD_NEED_PRTY ASC, IMMD_NEEDS.TMPL_ID DESC, IMMD_NEEDS.QTY_REQD DESC
 
 



PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------

-------------------------------------------------------------------------------
| Id  | Operation                    |  Name          | Rows  | Bytes | Cost  |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                |     1 |   100 |   657 |
|   1 |  SORT ORDER BY               |                |     1 |   100 |   657 |
|*  2 |   TABLE ACCESS BY INDEX ROWID| IMMD_NEEDS     |     1 |   100 |   653 |
|*  3 |    INDEX RANGE SCAN          | PK_IMMD_NEEDS  | 15725 |       |    43 |
-------------------------------------------------------------------------------

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

   2 - filter("IMMD_NEEDS"."SHPMT_NBR"=:Z AND "IMMD_NEEDS"."SKU_ID"=:Z AND
              "IMMD_NEEDS"."STAT_CODE"=TO_NUMBER(:Z) AND ("IMMD_NEEDS"."CASE_NBR"=:Z OR
              "IMMD_NEEDS"."CASE_NBR" IS NULL) AND ("IMMD_NEEDS"."PO_NBR"=:Z OR
              "IMMD_NEEDS"."PO_NBR" IS NULL))
   3 - access("IMMD_NEEDS"."WHSE"=:Z)

Note: cpu costing is off

 

 

Same query with hint: /*+FULL(IMMD_NEEDS)*/

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------

--------------------------------------------------------------------
| Id  | Operation            |  Name       | Rows  | Bytes | Cost  |
--------------------------------------------------------------------
|   0 | SELECT STATEMENT     |             |     1 |   100 |    85 |
|   1 |  SORT ORDER BY       |             |     1 |   100 |    85 |
|*  2 |   TABLE ACCESS FULL  | IMMD_NEEDS  |     1 |   100 |    81 |
--------------------------------------------------------------------

 

A 10053 of the EXPLAIN PLAN without the hint gives:

 

***************************************
SINGLE TABLE ACCESS PATH
Column:       WHSE  Col#: 1      Table: IMMD_NEEDS   Alias: IMMD_NEEDS
    NDV: 2         NULLS: 0         DENS: 1.5898e-05
    FREQUENCY HISTOGRAM: #BKT: 31450 #VAL: 2
Column:  SHPMT_NBR  Col#: 3      Table: IMMD_NEEDS   Alias: IMMD_NEEDS
    NDV: 1         NULLS: 6         DENS: 1.0000e+00
    NO HISTOGRAM: #BKT: 1 #VAL: 2
Column:     SKU_ID  Col#: 6      Table: IMMD_NEEDS   Alias: IMMD_NEEDS
    NDV: 14950     NULLS: 3         DENS: 6.6890e-05
    NO HISTOGRAM: #BKT: 1 #VAL: 2
Column:  STAT_CODE  Col#: 30     Table: IMMD_NEEDS   Alias: IMMD_NEEDS
    NDV: 3         NULLS: 0         DENS: 3.3333e-01 LO:  0  HI: 99
    NO HISTOGRAM: #BKT: 1 #VAL: 2
Column:   CASE_NBR  Col#: 4      Table: IMMD_NEEDS   Alias: IMMD_NEEDS
    NDV: 5823      NULLS: 6         DENS: 3.1803e-05
    HEIGHT BALANCED HISTOGRAM: #BKT: 200 #VAL: 39
Column:     PO_NBR  Col#: 5      Table: IMMD_NEEDS   Alias: IMMD_NEEDS
    NDV: 1         NULLS: 21        DENS: 1.0000e+00
    NO HISTOGRAM: #BKT: 1 #VAL: 2
  TABLE: IMMD_NEEDS     ORIG CDN: 31450  ROUNDED CDN: 1  CMPTD CDN: 0
  Access path: tsc  Resc:  81  Resp:  81
  Skip scan: ss-sel 0  andv 15725
 Access path: tsc  Resc:  81  Resp:  81
  Skip scan: ss-sel 0  andv 15725
    ss cost 15725
    index io scan cost 0
  Access path: index (scan)
      Index: PK_IMMD_NEEDS
  TABLE: IMMD_NEEDS
      RSC_CPU: 0   RSC_IO: 653
  IX_SEL:  5.0000e-01  TB_SEL:  5.0000e-01
  BEST_CST: 653.00  PATH: 4  Degree:  1
***************************************


GENERAL PLANS
***********************
Join order[1]:  IMMD_NEEDS[IMMD_NEEDS]#0
ORDER BY sort
    SORT resource      Sort statistics
      Sort width:           27 Area size:      131072 Max Area size:     5032960
   Degree: 1
      Blocks to Sort:        1 Row size:          120 Rows:          1
      Initial runs:          1 Merge passes:        1 IO Cost / pass:          6
      Total IO sort cost: 4
      Total CPU sort cost: 0
      Total Temp space used: 0

      Total CPU sort cost: 0
      Total Temp space used: 0
Best so far: TABLE#: 0  CST:        657  CDN:          1  BYTES:        100
    SORT resource      Sort statistics
      Sort width:           27 Area size:      131072 Max Area size:     5032960
   Degree: 1
      Blocks to Sort:        1 Row size:          120 Rows:          1
      Initial runs:          1 Merge passes:        1 IO Cost / pass:          6
      Total IO sort cost: 4
      Total CPU sort cost: 0
      Total Temp space used: 0
prefetching is on for PK_IMMD_NEEDS
Final - First Rows Plan:
  JOIN ORDER: 1
  CST: 657  CDN: 1  RSC: 656  RSP: 656  BYTES: 100
  IO-RSC: 656  IO-RSP: 656  CPU-RSC: 0  CPU-RSP: 0
  First Rows Plan
=====================


 

So, it looks to me like the FTS is cheaper, and the optimizer knows it. So why doesn't it choose it unless I ask it to?
 
 
Stuart
©2008 dba.5341.com - Jax Systems, LLC, U.S.A.