05.11.2015 Views

Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

468<br />

CHAPTER 11 ■ INDEXES<br />

Execution Plan<br />

----------------------------------------------------------<br />

0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=1 Card=1 Bytes=13)<br />

1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (TABLE) (Cost=1 Card=1 Bytes=13)<br />

2 1 INDEX (RANGE SCAN) OF 'T_IDX' (INDEX) (Cost=1 Card=1)<br />

This is because the database is now not only rewriting the function in the CREATE INDEX, but<br />

also in the query itself, so they match.<br />

The workaround in prior releases is to do one of the following:<br />

• Use DECODE instead of CASE, as DECODE is not rewritten <strong>and</strong> what you see is what you get.<br />

• Use the searched CASE syntax in the first place (anticipate the optimization that will take<br />

place).<br />

But in any situation where your function-based index is not getting used <strong>and</strong> you cannot<br />

see any good reason why it should not be, check out USER_IND_EXPRESSIONS to verify that you<br />

are using the correct function.<br />

Caveat Regarding ORA-01743<br />

One quirk I have noticed with function-based indexes is that if you create one on the built-in<br />

function TO_DATE, it will not succeed in some cases, for example:<br />

ops$tkyte@ORA10GR1> create table t ( year varchar2(4) );<br />

Table created.<br />

ops$tkyte@ORA10GR1> create index t_idx on t( to_date(year,'YYYY') );<br />

create index t_idx on t( to_date(year,'YYYY') )<br />

*<br />

ERROR at line 1:<br />

ORA-01743: only pure functions can be indexed<br />

This seems strange, since we can sometimes create a function using TO_DATE, for example:<br />

ops$tkyte@ORA10GR1> create index t_idx on t( to_date('01'||year,'MMYYYY') );<br />

Index created.<br />

The error message that accompanies this isn’t too illuminating either:<br />

ops$tkyte@ORA10GR1> !oerr ora 1743<br />

01743, 00000, "only pure functions can be indexed"<br />

// *Cause: The indexed function uses SYSDATE or the user environment.<br />

// *Action: PL/SQL functions must be pure (RNDS, RNPS, WNDS, WNPS). SQL<br />

// expressions must not use SYSDATE, USER, USERENV(), or anything<br />

// else dependent on the session state. NLS-dependent functions<br />

// are OK.<br />

We are not using SYSDATE. We are not using the “user environment” (or are we?). No<br />

PL/SQL functions are used, <strong>and</strong> nothing about the session state is involved. The trick lies in<br />

the format we used: YYYY. That format, given the same exact inputs, will return different<br />

, anytime in the month of May

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!