Free Newsletters:
Database Journal  
DBAnews  

DBASupport

 The Knowledge Center for Oracle Professionals

Search DBAsupport:
 
HOME 11g Central 10g Central 9i Central 8i Central Oracle News Scripts FAQ OCP Zone Resources Technical Docs Tools & Utilities Forums
internet.com

» HOME
» FEATURES
    11g Central
    10g Central
    9i Central
    8i Central
    Oracle News
» COMMUNITY
    Scripts
    Forums
    FAQ
    OCP Zone
» RESOURCES
    Resources
    Technical Docs
    Tools & Utilities
    Tech Jobs
Marketplace Partners
Become a Marketplace Partner


internet.commerce
Be a Commerce Partner












internet.com
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers


   DBAsupport.com > Oracle > Oracle 8i Central > Featured Stories




Webmethods Developer
The Computer Merchant, Ltd
US-MA-Westwood

Justtechjobs.com Post A Job | Post A Resume


One of the many new features in Oracle 8i is the Function-Based Index (we will refrain from using FBI, but only just). This allows the DBA to create indexes on functions or expressions; these functions can be user generated pl/sql functions, standard SQL functions (non-aggregate only) or even a C callout.

A classic problem the DBA faces in SQL Tuning is how to tune those queries that use function calls in the where clause, and result in indexes created on these columns not to be used.

Example

Standard B-Tree index on SURNAME with cost based optimizer

create index non_fbi on sale_contacts (surname);
analyze index non_fbi compute statistics;
analyze table sale_contacts compute statistics;
SELECT count(*) FROM sale_contacts
WHERE UPPER(surname) = 'ELLISON';

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=1 Bytes=17)
     1 0 SORT (AGGREGATE)
          2 1 TABLE ACCESS (FULL) OF 'SALES_CONTACTS' (Cost=3 Card=16 Bytes=272)

Now we use a function based index

create index fbi on sale_contacts (UPPER(surname));
analyze index fbi compute statistics;
analyze table sale_contacts compute statistics;
SELECT count(*) FROM sale_contacts WHERE UPPER(surname) = 'ELLISON';


Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=17)
      1 0 SORT (AGGREGATE)
            2 1 INDEX (RANGE SCAN) OF 'FBI' (NON-UNIQUE) (Cost=2 Card=381 Bytes=6477)

The function-based index has forced the optimizer to use index range scans (retuning zero or more rowids) on the surname column rather than doing a full table scan (non-index lookup). Optimal performance does vary depending on table size, uniqueness and selectivity of columns, use of fast full table scans etc. Therefore try both methods to gain optimal performance in your database.

It is important to remember that the function-based B*Tree index does not store the expression results in the index but uses an "expression tree". The optimizer performs expression matching by parsing the expression used in the SQL statement and comparing the results against the expression-tree values in the function-based index. This comparison IS case sensitive (ignores spaces) and therefore your function-based index expressions should match expressions used in the SQL statement where clauses.

Init.ora Parameters

The following parameter must be set in your parameter file: QUERY_REWRITE_INTEGRITY = TRUSTED
QUERY_REWRITE_ENABLED = TRUE
COMPATIBLE = 8.1.0.0.0 (or higher)

Grants

Grants To create function-based indexes the user must be granted CREATE INDEX and QUERY REWRITE, or alternatively be granted CREATE ANY INDEX and GLOBAL QUERY REWRITE. The index owner must have EXECUTE access on the function used for the index. If execute access is revoked then the function-based index will be "disabled" (see dba_indexes).

Disabled Indexes

If your function-based index has a status of "disabled" the DBA can do one of the following:
a) drop and create the index (take note of its current settings)
b) alter index enable, function-based indexes only, also use disable keyword as required
c) alter index unusable.

Queries on a DISABLED index fail if the optimizer chooses to use the index.Here is an example ORA error:
ERROR at line 1: ORA-30554: function-based index MYUSER.FBI is disabled.

All DML operations on a DISABLED index also fail unless the index is also marked UNUSABLE and the initialization parameter SKIP_UNUSABLE_INDEXES is set to true.

Some more Examples

CREATE INDEX expression_ndx
ON mytable ((mycola + mycolc) * mycolb);

SELECT mycolc FROM mytable
WHERE (mycola + mycolc) * mycolb <= 256;


..or a composite index..

CREATE INDEX example_ndx
ON myexample (mycola, UPPER(mycolb), mycolc);

SELECT mycolc FROM myexample
WHERE mycola = 55 AND UPPER(mycolb) = 'JONES';

Restriction & Rule Summary

The following restrictions apply to function based indexes. You may not index:
a) LOB columns
b) REF
c) Nested table column
d) Objects types with any of the above data types.

Function-based indexes must always follow these rules:
a) Cost Based optimizer only, must generate statistics after the index is created
b) Can not store NULL values (function can not return NULL under any circumstance)
c) If a user defined pl/sql routine is used for the function-based index, and is invalidated, the index will become "disabled"
d) Functions must be deterministic (always return the same value for a known input)
e) The index owner must have "execute" access on function used in the function-based index. Revocation of the privilege will render the index "disabled"
f) May have a B-Tree and Bitmap index type only
g) Can not use expressions that are based on aggregate functions, ie. SUM, AVG etc.
h) To alter a function-based index as enabled, the function used must be valid, deterministic and the signature of the function matches the signature of the function when it was created.


DBAsupport.com Home Page