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!

Bind Peeking only for "known" columns?

fjfrankenJan 14 2015 — edited Jan 15 2015

Hi all,

We are working on our 11.2.0.3 RAC (on AIX 7.1) database on trying to figure out why a certain repeated query ( batch load) is not using the correct execution plan.

The query itself looks like:

select CATENTRY_ID from CATENTRY where ((PARTNUMBER=:1 ) OR ((0 = :2 ) AND (PARTNUMBER IS NULL))) and ((MEMBER_ID=:3 ) OR ((0 = :4 ) AND (MEMBER_ID IS NULL)));

This query is an IBM Webshere internal query, which therefore is unchangeable.

The table in question has an Index available on PARTNUMBER & MEMBER_ID

The execution plan however looks like

The execution plan of the above statement looks like:

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer Mode=ALL_ROWS (Cost=2038 Card=1 Bytes=23)

1 0 TABLE ACCESS FULL WCSADMIN.CATENTRY (Cost=2038 Card=1 Bytes=23)

So a FTS scan is used where an Index-lookup would be expected.

The values passed to this query are e.g.:

:1 = XA-GED-1068849

:2 = 1

:3 = -6000

:4 = 1

With the part of the WHERE CLAUSE then having ((0=1) AND (PARTNUMBER IS NULL)) and the same for ((0=1) AND (MEMBER_ID IS NULL)) would result in an Index lookup.:

select

catentry_id

from catentry

where ( (partnumber = 'XA-GED-5702810')

  or ( (0 = 1)

  and (partnumber is null)))

and ( (member_id = -6000)

  or ( (0 = 1)

  and (member_id is null))) ;

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer Mode=ALL_ROWS (Cost=3 Card=1 Bytes=23)

1 0 TABLE ACCESS BY INDEX ROWID WCSADMIN.CATENTRY (Cost=3 Card=1 Bytes=23)

2 1 INDEX UNIQUE SCAN WCSADMIN.I0000064 (Cost=2 Card=1)

Somewhere in the parsing of the query the optimizer does not have/use all the information needed to determine the correct plan, allthough the tracefile shows all values are captured correctly

I would expect that the optimizer would "PEEK" all available variables to determine the best execution plan.

It looks however that the two BINDs for the "0=:2" and "0=:4" are not "peeked" and therefore not used, which results in a Full Table Scan as the PARTNUMBER IS NULL and MEMBER_ID IS NULL are not skipped.

Can anyone confirm that only BINDs for "existing/real" columns are peeked??

And is this configurable ??

Thanks

FJ Franken

This post has been answered by Jonathan Lewis on Jan 14 2015
Jump to Answer

Comments

Frank Kulash

Hi, @kannan-sekar
Is this thread a duplicate of: Unique Index not allowing to insert rows into table.. — oracle-tech
If so, one of them should be closed right away. It's confusing (and counter-productive) to have multiple threads for the same question. (This may not be your fault; the site can behave strangely.)

Frank Kulash

Hi,
I am unable to replicate the issue here, instead i explained in words below.
That makes it hard (perhaps impossible) to solve the problem. What problem do you have in producing a test case that the people who want to help you can replicate?
Step1: Creating table with primary key on col1
CREATE TABLE T1(PKEY NUMBER(10) PRIMARY KEY, ACCT_NO NUMBER(10), ACCT_KEY NUMBER(10), ACCT_STATUS NUMBER(1), ACCT_GRP_STATUS NUMBER(1));
The table created above doesn't have a column called col1. If you have a problem with some table that has a column called col1, post the CREATE TABLE and INSERT statements for that table.
Step2: Creating unique index on using CASE statement
CREATE UNIQUE INDEX IDX_T1_ACCT_KEY ON T1 ( CASE WHEN ACCT_STATUS = 1 AND ACCT_GRP_STATUS = -1 THEN ACCT_KEY ELSE NULL END);
Explain the requirement that the index is supposed to meet. For example, "I need to make sure that among all the rows with the same acct_key value, no more than one of them has acc_status=1 and acct_grp_status=-1."
By the way, that index uses a CASE expression, not a CASE statement. A CASE statement is something different. You'll get better answers faster if you say what you mean.
Below kind of row value is not inserted in my real world (getting unique index error).
Are you sure the index you posted is causing the error? Post the exact, complete error message you get.

1 - 2
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Feb 12 2015
Added on Jan 14 2015
15 comments
3,347 views