Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Usenet -> c.d.o.server -> Q: why does CBO not use available indices

Q: why does CBO not use available indices

From: Anke Heinrich <anke.heinrich_at_marconi.com>
Date: 6 Oct 2003 10:03:00 -0700
Message-ID: <9042145d.0310060903.4ed4e354@posting.google.com>


Hi,

I have a problem getting the cost based optimizer to use the available indices instead of performing a full table scan. Using hints is not possible as I can't change the source code at the moment. I've heard about outlines, but I'm not sure if this works for us.

I don't have much experience with query optimization or export/import of outlines, so any help from you is greatly appreciated. The facts follow:

SQL statement:

select * from TP, ETP
where ( TP.FK_RESOURCE_ETP = ETP.ID ) and ( ETP.FOREIGN_ID = ? ) order by ETP.FK_CONTAINER_EMLSN, ETP.FOREIGN_TYPE, ETP.FOREIGN_LABEL

best select strategy:
1) search for entries in ETP with given FOREIGN_ID

   using index ETP_FOREIGN_ID on ETP (FOREIGN_ID) which is not unique,    but very selective (usually only one match) 2) join the results from ETP with TP.FK_RESOURCE_ETP = ETP.ID

   using unique index TP_KEY_RESOURCE on TP (FK_RESOURCE_ETP) 3) sort results

table statistics:
have been calculated using
analyze table TP compute statistics
for all indexes for all indexed columns; analyze table ETP compute statistics
for all indexes for all indexed columns;

optimizer parameter:
optimizer_index_cost_adj=10
optimizer_max_permutations=1000

we've had a good execution plan when both tables had around 400 entries:

   0 SELECT STATEMENT Optimizer=CHOOSE    1 0 SORT (ORDER BY)

   2    1     NESTED LOOPS
   3    2       TABLE ACCESS (BY INDEX ROWID) OF 'ETP'
   4    3         INDEX (RANGE SCAN) OF 'ETP_FOREIGN_ID' (NON-UNIQUE)
   5    2       TABLE ACCESS (BY INDEX ROWID) OF 'TP'
   6    5         INDEX (UNIQUE SCAN) OF 'TP_KEY_RESOURCE' (UNIQUE)

with around 35000 entries (and updated statistics) the execution plan now is:

   0 SELECT STATEMENT Optimizer=CHOOSE    1 0 SORT (ORDER BY)

   2    1     MERGE JOIN
   3    2       TABLE ACCESS (BY INDEX ROWID) OF 'ETP'
   4    3         INDEX (FULL SCAN) OF 'ETP_ID' (UNIQUE)
   5    2       SORT (JOIN)
   6    5         TABLE ACCESS (FULL) OF 'TP'

we tried out the hint which produced the preferred execution plan, but as I said we can't change the source code, so this is not a real option:

/*+ USE_NL(ETP TP) INDEX(ETP ETP_FOREIGN_ID) INDEX(TP TP_KEY_RESOURCE) */ performance difference is 0.04 with good old plan, 0.46 with new one :-(

Is there a way to force the optimizer to use a specific plan for dynamically generated statements without changing source code?

Are there any other options left?

Thanks in advance,
Anke Received on Mon Oct 06 2003 - 12:03:00 CDT

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US