Performance problem on function-based index

Hi guys,
I am having performance problems with the addition of new function-based indexes.
alter session set nls_comp='ANSI';
alter session set nls_sort='BINARY_CI';
* have to run this because the of case-insensitivity requirements
I have a view. for ex:
create or replace view view1
as
select * from emp1,user
where emp1.empno=user.empno
union
select * from emp2,user
where emp2.empno=user.empno
union
select * from emp3,user
where emp3.empno=user.empno and so on
When I run this it works with a full table scan. Then when i created a function-based index:
create index user_ix on
user(nlssort(empno,'NLS_SORT=BINARY_CI'));
analyze index user_ix compute statistics;
analyze table user compute statistics;
the view hangs. but when i run the individual select statements it works.
Do you guys have any idea on what's going on? Any advise is greatly appreciated.
Thanks.

LC is absolutely right. Brain cramp on my part.
On the other hand, I can't seem to coerce Oracle to apply a to_binary_double conversion as part of an implicit conversion.
var bin_dbl binary_double;
select to_binary_double(14) into :bin_dbl from dual;
SCOTT @ nx102 JCAVE9420> select * from emp where empno = :bin_dbl;
no rows selected
Elapsed: 00:00:00.14
Execution Plan
Plan hash value: 2949544139
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
|   0 | SELECT STATEMENT            |        |     1 |    39 |     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    39 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | PK_EMP |     1 |       |     0   (0)| 00:00:01 |
Predicate Information (identified by operation id):
   2 - access("EMPNO"=TO_NUMBER(:BIN_DBL))I'd expect that Oracle would try to convert the binary double to a number, not the other way around.
Justin

Similar Messages

  • Differences between function based index and normal index

    Hi,
    Please Give me some differences between function based index and normal indexes.
    1. Is there any performance gain in function based index?
    2. Why indexes created in DESC are treated as function based?
    3. Every DESC index is b-tree index?
    Thanks

    check this link. This would give u a basic idea of what a function based index is .
    http://www.oracle-base.com/articles/8i/FunctionBasedIndexes.php
    --Prasad                                                                                                                                                                                                                                                                                                                                       

  • Function Based Indexes - negative performance

    Has anyone run across any cases where they have had issues with Function Based Indexes negatively impacting performance??
    We are trying to use function based indexes in 9i (NLS_SORT=GENERIC_BASELETTER) and 10g (NLS_SORT=BINARY_CI) for case insensitivity.
    We thought this was a decent solution until recently when testing with larger datasets. Any info is appreciated.
    Thanks,

    Just to clarify rreynoldson's first point:
    All indexes will negatively impact inserts. Indexes, including function-based indexes, may or may not improve update and delete performance depending on whether the overhead of maintaining the index outweighs the benefit of being able to use the index to find the row(s) to update relatively quickly.
    For user564260:
    Assuming those parameters are set, make sure that you've gathered statistics on the function based index. If that doesn't resolve the problem, can you post a small test case that demonstrates the problem where you
    - Create the table
    - Create the indexes
    - Populate it with data
    - Run the query that you'd expect to use the FBI
    - Post the explain plan
    that would help us immensely.
    Justin

  • Problem using two function based indexes at once!

    Hello Oracle!
    I've got problems using two function based indexes on geometries at once.
    The problem occures, when I use a spatial join between two geometries both using function based indexes.
    The test case:
    CREATE TABLE quad (centroid NUMBER);
    CREATE TABLE points (no NUMBER, point MDSYS.SDO_GEOMETRY);
    CREATE OR REPLACE FUNCTION getQuad (centroid NUMBER) RETURN MDSYS.SDO_GEOMETRY DETERMINISTIC IS
    BEGIN
    RETURN MDSYS.SDO_GEOMETRY(2003, NULL, NULL, MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1),MDSYS.SDO_ORDINATE_ARRAY(centroid-5,centroid-5,centroid+5,centroid-5,centroid+5,centroid+5,centroid-5,centroid+5,centroid-5,centroid-5));
    END;
    INSERT INTO USER_SDO_GEOM_METADATA VALUES('quad','tiedge.getQuad(centroid)',MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X', -100, 100, .0000001), MDSYS.SDO_DIM_ELEMENT('Y', -100, 100, .0000001)),NULL);
    CREATE INDEX quad_idx on quad(getQuad(centroid)) INDEXTYPE IS MDSYS.SPATIAL_INDEX;
    INSERT INTO quad VALUES (0);
    INSERT INTO quad VALUES (5);
    INSERT INTO quad VALUES (10);
    INSERT INTO points VALUES (1, MDSYS.SDO_GEOMETRY(1001,NULL,NULL,MDSYS.SDO_ELEM_INFO_ARRAY(1,1,1),MDSYS.SDO_ORDINATE_ARRAY(4,4)));
    ALTER SESSION SET QUERY_REWRITE_INTEGRITY=TRUSTED;
    ALTER SESSION SET QUERY_REWRITE_ENA[i]Long postings are being truncated to ~1 kB at this time.

    hi there,
    For a better audience for this question, I'd look at the database forum.
    guys on that will be a lot more familiar with FBIs
    thanks
    Barry

  • Function Based Index - Query Performance

    HI,
    Good Day to All..
    I'd like to use function based indexes on following column(to_char(ps.user_pc_id)).
    Whereas this column is part of PRIMARY KEY.
    Is it possible to create a function based index on PRIMARY KEY Column?
    Attached below is the query with the explain plan ...
    TO_CHAR Expression - Performance
    Thanks for your reply.

    DTYLER_APP@pssdev2> create table dt_fbi_pk(id varchar2(20));
    Table created.
    DTYLER_APP@pssdev2> drop table dt_fbi_pk;
    Table dropped.
    DTYLER_APP@pssdev2> create table dt_fbi(id number);
    Table created.
    DTYLER_APP@pssdev2> create index dt_fbi_idx on dt_fbi(to_char(id));
    Index created.
    DTYLER_APP@pssdev2> alter table dt_fbi add constraint dt_fbi_pk primary key (id);
    Table altered.
    DTYLER_APP@pssdev2> select constraint_name,constraint_type, index_name from user_constraints where table_name='DT_FBI';
    CONSTRAINT_NAME                C INDEX_NAME
    DT_FBI_PK                      P DT_FBI_PK
    1 row selected.When we created the primary key constraint, Oracle created a new index rather than using the existing one because....
    DTYLER_APP@pssdev2> alter table dt_fbi drop primary key;
    Table altered.
    DTYLER_APP@pssdev2> select index_name from user_indexes where table_name ='DT_FBI';
    INDEX_NAME
    DT_FBI_IDX
    1 row selected.
    DTYLER_APP@pssdev2> alter table dt_fbi add constraint dt_fbi_pk primary key (id) using index dt_fbi_idx;
    alter table dt_fbi add constraint dt_fbi_pk primary key (id) using index dt_fbi_idx
    ERROR at line 1:
    ORA-14196: Specified index cannot be used to enforce the constraint.
    DTYLER_APP@pssdev2> alter table dt_fbi add constraint dt_fbi_uk unique(id) using index dt_fbi_idx;
    alter table dt_fbi add constraint dt_fbi_uk unique(id) using index dt_fbi_idx
    ERROR at line 1:
    ORA-14196: Specified index cannot be used to enforce the constraint.We can't use a function based index to enforce a unique or primary key constraint. Changing the syntax does not help..
    DTYLER_APP@pssdev2> alter table dt_fbi add constraint dt_fbi_uk unique(TO_CHAR(id)) using index dt_fbi_idx;
    alter table dt_fbi add constraint dt_fbi_uk unique(TO_CHAR(id)) using index dt_fbi_idx
    ERROR at line 1:
    ORA-00904: : invalid identifierWe can create a unique index however
    DTYLER_APP@pssdev2> drop index dt_fbi_idx;
    Index dropped.
    DTYLER_APP@pssdev2> create unique index dt_fbi_idx on dt_fbi(to_char(id));
    Index created.but we still can't use it to enforce a unique or primary key constraint
    DTYLER_APP@pssdev2> alter table dt_fbi add constraint dt_fbi_pk primary key (id) using index dt_fbi_idx;
    alter table dt_fbi add constraint dt_fbi_pk primary key (id) using index dt_fbi_idx
    ERROR at line 1:
    ORA-14196: Specified index cannot be used to enforce the constraint.
    DTYLER_APP@pssdev2> alter table dt_fbi add constraint dt_fbi_uk unique(id) using index dt_fbi_idx;
    alter table dt_fbi add constraint dt_fbi_uk unique(id) using index dt_fbi_idx
    ERROR at line 1:
    ORA-14196: Specified index cannot be used to enforce the constraint.So no, you can't use it for a primary key. If you just want to enforce uniqueness then yes, you can do it with a unique index, but not a constraint.
    DTYLER_APP@pssdev2> select * from v$version;
    BANNER
    Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
    PL/SQL Release 10.2.0.4.0 - Production
    CORE    10.2.0.4.0      Production
    TNS for Linux: Version 10.2.0.4.0 - Production
    NLSRTL Version 10.2.0.4.0 - Production
    5 rows selected.HTH
    Daviid

  • Problem creating a function based index

    Hi,
    Database: 8.0.6
    OS: win 2000 server
    I want to create a function based index as shown below:
    sql> create index new_index on A_INP_PATIENTS_ADMT(bus_unit, admit_status_flag, nvl(clinical_discharge_yn,'N'), ward_code)
    When i press return its showing error,
    "ORA-00907: missing right parenthesis"
    Please show me how to rewrite this query to build function based index.
    Best Regards,
    Edited by: ateeqrahman on Jun 6, 2010 2:34 PM

    Your sql is fine:
    SQL> CREATE TABLE A_INP_PATIENTS_ADMT(
      2                                   bus_unit number,
      3                                   admit_status_flag varchar2(1),
      4                                   clinical_discharge_yn varchar2(1),
      5                                   ward_code varchar2(10)
      6                                  )
      7  /
    Table created.
    SQL> create index new_index on A_INP_PATIENTS_ADMT(bus_unit, admit_status_flag, nvl(clinical_discharge_yn,'N'), ward_code)
      2  /
    Index created.
    SQL> You did not post Oracle version. Most likely, you are on some older version that does not support FBI. Otherwise, post your version and table description and create index statement execution showing all errors you are getting.
    SY.

  • Function-based Index and an OR-condition in the WHERE-clause

    We have some problems with functin-based indexes and
    the or-condition in a where-clause.
    (We use oracle 8i (8.1.7))
    create table TPERSON(ID number(10),NAME varchar2(20),...);
    create index I_NORMAL_TPERSON_NAME on TPERSON(NAME);
    create index I_FUNCTION_TPERSON_NAME on TPERSON(UPPER(NAME));
    The following two statements run very fast on a large table
    and the execution-plan asure the usage of the indexes
    (-while the session is appropriate configured and the table is analyzed):
    1)     select count(ID) FROM TPERSON where upper(NAME) like 'MIL%';
    2)     select count(ID) from TPERSON where NAME like 'Mil%' or (3=5);
    In particular we see that a normal index is used while the where-clause contains
    an OR-CONDITION.
    But if we try the similarly select-statement
    3)     select count(ID) FROM TPERSON where upper(NAME) like 'MIL%' or (3=5);
    the CBO will not use the function-index.
    (This behavior we only expect with views but not with indexes.)
    We ask for an advice like an hint, which enable the CBO-usage
    of function-based indexes in connection with OR.
    This problem seems to be artificial because it contains this dummy logic:
         or (3=5).
    This steams from an prepared statement, where this kind of boolean
    flag reduce the amount of different select-statements needed for
    covering the hole business-logic, while using bind-variables for the
    concrete query-parameters.
    A more realistic (still boild down) version of our prepared select-statement run in
    SQL Plus:
    define x_name = 'MIL%';
    define x_firstname = '';
    select * FROM TPERSON
    where (upper(NAME) like '&x_name' or ( '&x_name' = ''))
    and (upper(FIRSTNAME) like '&x_firstname' or ('&x_firstname' = ''))
    and ...;
    In particular we dont refernce the tablecolumn , but the QUERY-Parameter
    yield the second boolean value in the or-condition.
    The problem is that this condition ('&x_name' = '') dont use any index.
    thanks a lot for spending your time with this problem

    Try
    SELECT /*+ RULE */
    as your hint. I don't have the book with me, but this last weekend I read a section about your very problem. The book was a Oracle Press gold cover about Oracle 8i Performance tuning. If you e-mail me I can quote you the chapter when I get home Friday.

  • Impdp not importing function based index correctly.

    We noticed that a process running in our develop database was running much faster than in the production database. After investigating we found that on the development database the process was using an index on the main large table and on the production database the index was ignored and full table scans of the large table were being used.
    The data in the tables was the same, statistics were up-to-date, etc. Looking closer we saw that the index on the production database was function based because it had the DESC keyword on one column in the index. On the development database all columns of the index were ASC and thus it was a "normal" index. This was very confusing since we had just refreshed the development database from production using expdp/impdp. I ran impdp with the sqlfiles option to capture the DDL from the export file for the index in question from the production database:
    CREATE UNIQUE INDEX "SYSADM"."PS_SF_1098_ITEM" ON "SYSADM"."PS_SF_1098_ITEM" ("EMPLID", "SF_TIN", "CALENDAR_YEAR", "SEQ_NO" DESC, "DTL_SEQ_NBR")
    PCTFREE 10 INITRANS 2 MAXTRANS 255
    STORAGE(INITIAL 40960 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
    TABLESPACE "PSINDEX" ;
    I then dropped the table/index in the development database and reimported just this one table. Sure enough, the index wasn't created as a function based index (no DESC keyword on SEQ_NO column):
    CREATE UNIQUE INDEX "SYSADM"."PS_SF_1098_ITEM" ON "SYSADM"."PS_SF_1098_ITEM" ("EMPLID", "SF_TIN", "CALENDAR_YEAR", "SEQ_NO", "DTL_SEQ_NBR")
    PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
    STORAGE(INITIAL 40960 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
    TABLESPACE "PSINDEX" ;
    I've researched this extensively and can't find any information on why this is happening. Any ideas before I open a SR?
    BTW.... version is 11.1.0.7 patchset 31 on Windows Server 2003. Both dev and prod environments are identical.
    Thanks,
    Dan

    Working on something else I noticed the following two "hidden" init.ora parameters in both my dev and production databases:
    *._disable_function_based_index=TRUE
    *._ignore_desc_in_index=TRUE
    The first parameter explains why the index (function based) was being ignored in my production database. The second explains why the index is created without the DESC keyword in my dev database from an export from my prod database. I guess you do learn something new every day :)
    These databases are used by Peoplesoft applications and I found several posts saying that function based indexes created by Peoplesoft were causing performance and/or data validity problems and users were instructed to set the above parameters so the FIB's weren't used. So, everything is working as expected/designed. I will contact Peoplesoft Tech Support to see if users are still encouraged to set the above parameters.
    Dan

  • Function based indexes on object tables

    Hi,
    I am trying to create a function based index on an object table. I am getting the following error:
    SQL> create index cell1_indx on cell1(create_cell1(id)) indextype is mdsys.spatial_index;
    create index cell1_indx on cell1(create_cell1(id)) indextype is mdsys.spatial_index
    ERROR at line 1:
    ORA-29855: error occurred in the execution of ODCIINDEXCREATE routine
    ORA-13249: internal error in Spatial index: [mdidxrbd]
    ORA-13249: Error in Spatial index: index build failed
    ORA-13249: Stmt-Execute Failure: SELECT num_rows from all_tables where owner='ASHE' and table_name=
    'CELL1'
    ORA-06512: at "MDSYS.SDO_INDEX_METHOD_9I", line 7
    ORA-06512: at line 1
    Here cell1 is an object table.
    Is the procedure for creating function based indexes on object tables different from relational tables?
    Chinni

    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.
    Joel P�rez

  • Function based indexes doing full table scan

    Guys,
    I am testing function based indexes and whatever I do
    it is doing a full table scan.
    1)I have set the following init parameters as
    QUERY_REWRITE_ENABLED=TRUE
    QUERY_REWRITE_INTEGRITY=TRUSTED
    2)CREATE INDEX i3 ON emp(UPPER(ename));
    3) ANALYZE TABLE emp COMPUTE STATISTICS
    ANALYZE INDEX I3 COMPUTE STATISTICS
    4) DELETE plan_table;
    5) EXPLAIN PLAN SET statement_id='Test1' FOR
    SELECT ename FROM emp WHERE UPPER(ename) = 'KING';
    6) SELECT LPAD(' ',2*level-2)||operation||' '||options||' '||object_name
    query_plan
    FROM plan_table
    WHERE statement_id='Test1'
    CONNECT BY prior id = parent_id
    START WITH id = 0 order by id
    7) And the query plan shows as
    SELECT STATEMENT
    TABLE ACCESS FULL EMP
    I am using 9.0.1.4 !!!
    Any help is appreciated !!!
    Regards,
    A.Kishore

    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.
    Joel P�rez

  • How to check which function was used in a function based index.

    Hi how can i check which function was used in a function based index created on a column.
    Thanks

    Hi,
    What is your requirement... !!
    Bascially performing a function on an indexed column in the where clause of a query guaranteed an index would not be used. From Oracle 8i onwards introduced Function Based Indexes to counter this problem.
    Any how check this..you will get an idea..
    http://www.akadia.com/services/ora_function_based_index_2.htm
    http://www.oracle-base.com/articles/8i/FunctionBasedIndexes.php
    -Pavan Kumar N

  • Function-based index with OR in the wher-clause

    We have some problems with functin-based indexes and
    the or-condition in a where-clause.
    --We use Oracle 8i (8.1.7)
    create table TPERSON(ID number(10),NAME varchar2(20),...);
    create index I_NORMAL_TPERSON_NAME on TPERSON(NAME);
    create index I_FUNCTION_TPERSON_NAME on TPERSON(UPPER(NAME));
    The following two statements run very fast on a large table
    and the execution-plan asure the usage of the indexes
    (-while the session is appropriate configured and the table is analyzed):
    1)     select count(ID) FROM TPERSON where upper(NAME) like 'MIL%';
    2)     select count(ID) from TPERSON where NAME like 'Mil%' or (3=5);
    In particular we see that a normal index is used while the where-clause contains
    an OR-CONDITION.
    But if we try the similarly select-statement
    3)     select count(ID) FROM TPERSON where upper(NAME) like 'MIL%' or (3=5);
    the CBO will not use the function-index I_FUNCTION_TPERSON_NAME and we have a full table scan in the execution-plan.
    (This behavior we only expect with views but not with indexes.)
    We ask for an advice like a hint, which enable the CBO-usage
    of function-based indexes in connection with OR.
    This problem seems to be artificial because it contains this dummy logic:
         or (3=5).
    This steams from an prepared statement, where this kind of boolean
    flag reduce the amount of different select-statements needed for
    covering the hole business-logic, while using bind-variables for the
    concrete query-parameters.
    A more realistic (still boild down) version of our select-statement is:
    select * FROM TPERSON
    where (upper(NAME) like 'MIL%' or (NAME is null))
    and (upper(FIRSTNAME) like 'MICH% or (FIRSTNAME is null))
    and ...;
    thank you for time..
    email: [email protected]

    In the realistic statement you write :
    select * FROM TPERSON
    where (upper(NAME) like 'MIL%' or (NAME is null))
    and (upper(FIRSTNAME) like 'MICH% or (FIRSTNAME is null))
    and ...;
    as far as i know, NULL values are not indexed, "or (NAME is NULL)" have to generate a full table scan.
    HTH
    We have some problems with functin-based indexes and
    the or-condition in a where-clause.
    --We use Oracle 8i (8.1.7)
    create table TPERSON(ID number(10),NAME varchar2(20),...);
    create index I_NORMAL_TPERSON_NAME on TPERSON(NAME);
    create index I_FUNCTION_TPERSON_NAME on TPERSON(UPPER(NAME));
    The following two statements run very fast on a large table
    and the execution-plan asure the usage of the indexes
    (-while the session is appropriate configured and the table is analyzed):
    1)     select count(ID) FROM TPERSON where upper(NAME) like 'MIL%';
    2)     select count(ID) from TPERSON where NAME like 'Mil%' or (3=5);
    In particular we see that a normal index is used while the where-clause contains
    an OR-CONDITION.
    But if we try the similarly select-statement
    3)     select count(ID) FROM TPERSON where upper(NAME) like 'MIL%' or (3=5);
    the CBO will not use the function-index I_FUNCTION_TPERSON_NAME and we have a full table scan in the execution-plan.
    (This behavior we only expect with views but not with indexes.)
    We ask for an advice like a hint, which enable the CBO-usage
    of function-based indexes in connection with OR.
    This problem seems to be artificial because it contains this dummy logic:
         or (3=5).
    This steams from an prepared statement, where this kind of boolean
    flag reduce the amount of different select-statements needed for
    covering the hole business-logic, while using bind-variables for the
    concrete query-parameters.
    A more realistic (still boild down) version of our select-statement is:
    select * FROM TPERSON
    where (upper(NAME) like 'MIL%' or (NAME is null))
    and (upper(FIRSTNAME) like 'MICH% or (FIRSTNAME is null))
    and ...;
    thank you for time..
    email: [email protected]

  • Creation of function based index using escape

    Hello,
    I have the following SQL, sometimes performing bad:
    SELECT DISTINCT UPPER(A.PROCESSIDCODE), UPPER(A.RULENAME), CHARSET
    FROM XIB_DETECT A, XIB_PROCESSIDPROPERTIES B, XIB_RULES C
    WHERE ( A.KEY1 = :P1 OR ( :P1 like REPLACE(REPLACE(REPLACE(REPLACE(KEY1,'%', '\%'),'_', '\_'),'?', '_'),'*','%') escape '\' AND A.REGFLAGS1 = 'Y') OR A.KEY1 = '*' AND A.REGFLAGS1 = 'Y')
    AND (A.KEY2 = :P2 OR ( :P2 like REPLACE(REPLACE(REPLACE(REPLACE(KEY2,'%', '\%'),'_', '\_'),'?', '_'),'*','%') escape '\' AND A.REGFLAGS2 = 'Y') OR (A.KEY2 IS NULL AND A.REGFLAGS2 IS NULL ) )
    AND (A.KEY3 = :P3 OR ( :P3 like REPLACE(REPLACE(REPLACE(REPLACE(KEY3,'%', '\%'),'_', '\_'),'?', '_'),'*','%') escape '\' AND A.REGFLAGS3 = 'Y') OR (A.KEY3 IS NULL AND A.REGFLAGS3 IS NULL ) )
    AND (A.KEY4 = :P4 OR ( :P4 like REPLACE(REPLACE(REPLACE(REPLACE(KEY4,'%', '\%'),'_', '\_'),'?', '_'),'*','%') escape '\' AND A.REGFLAGS4 = 'Y') OR (A.KEY4 IS NULL AND A.REGFLAGS4 IS NULL ) )
    AND (A.KEY5 = :P5 OR ( :P5 like REPLACE(REPLACE(REPLACE(REPLACE(KEY5,'%', '\%'),'_', '\_'),'?', '_'),'*','%') escape '\' AND A.REGFLAGS5 = 'Y') OR (A.KEY5 IS NULL AND A.REGFLAGS5 IS NULL ) )
    AND (A.KEY6 IS NULL OR A.KEY6 = '*' AND REGFLAGS6 = 'Y')
    AND (A.KEY7 IS NULL OR A.KEY7 = '*' AND REGFLAGS7 = 'Y')
    AND (A.KEY8 IS NULL OR A.KEY8 = '*' AND REGFLAGS8 = 'Y')
    AND (A.KEY9 IS NULL OR A.KEY9 = '*' AND REGFLAGS9 = 'Y')
    AND (A.KEY10 IS NULL OR A.KEY10 = '*' AND REGFLAGS10 = 'Y')
    AND ( ( A.PROCESSIDCODE IS NOT NULL AND UPPER(A.PROCESSIDCODE) = UPPER(B.PROCESSIDCODE) AND A.XLEVEL = B.XLEVEL AND B.ACTIVEFLAG = 'Y' )
    OR ( A.RULENAME IS NOT NULL AND UPPER(A.RULENAME) = UPPER(C.RULENAME) AND A.XLEVEL = C.XLEVEL AND C.ACTIVEFLAG = 'Y' ) );
    Now I want to create a function based index on the key1 column:
    CREATE INDEX xib_detect_ix ON xib_detect (REPLACE(REPLACE(REPLACE(REPLACE(KEY1,'%', '\%'),'_', '\_'),'?', '_'),'*','%') escape '\') TABLESPACE ... ONLINE;
    However, this is not working with "escape" '\', throwing: ORA-00907: missing right parenthesis
    Any idea how to create an index on this construct with "escape"?
    Database version is 10.2.0.3.
    Thanks a lot.
    Regards
    Oliver

    Hi,
    You can get the "missing right parenthesis" error for many different syntax errors.
    In this case, you really are missing a right parenthesis.  Your statement has 5 left '('s, but only 4 right ')'s.  It's easy to see this if you format your code:
    CREATE  INDEX xib_detect_ix
    ON  xib_detect ( REPLACE ( REPLACE ( REPLACE ( REPLACE ( KEY1
                     escape '\'
    ESCAPE is an option that you can use with the LIKE operator.  It gives you a mechanism for cancelling the special meaning of symbols like '%'.    You're not using the LIKE operator to create the index.  You're only using REPLACE, and no characters have any special meaning in REPLACE, so there's no way (or reason) to escape them.  Use ESCAPE in queries that use LIKE, when appropriate.

  • FUNCTION-BASED INDEX ( ORACLE 8I NEW FEATURE )

    제품 : ORACLE SERVER
    작성날짜 : 2004-08-16
    FUNCTION-BASED INDEX ( ORACLE 8I NEW FEATURE )
    ==============================================
    SCOPE
    10g Standard Edition(10.1.0) 이상 부터 Function-based Index 기능이 지원된다.
    Explanation
    1. 개요
         Function-based index는, 함수(function)이나 수식(expression)으로 계산
    된 결과에 대해 인덱스를 생성하여 사용할 수 있는 기능을 제공한다.
         질의 수행 시 해당 함수나     수식을 처리하여     결과를 가져 오는 것이 아니라,
         인덱스 형태로 존재하는 미리 계산되어 있는 결과를 가지고 처리하므로
         성능 향상을 기할 수 있다.
    2. 제약사항
    1) aggregate function 에 대한 function-based index 생성 불가.
    (예 : sum(...) )
    2) LOB, REF, nested table 컬럼에 대한 function-based index 생성 불가.
    3. 주요 특징
         1) cost-based optimizer에 의해 사용됨.
         2) B*Tree / bitmap index로 생성 가능.
         3) 산술식 (arithmetic expression), PLSQL function, SQL built-in
    function 등에 적용 가능.
         4) 함수나 수식으로 처리된 결과에 대한 range scan 가능
         5) NLS SORT 지원
         6) SELECT/DELETE를 할 때마다 함수나 수식의 결과를 계산하는 것이 아니라
         INSERT/UPDATE 시 계산된 값을 인덱스에 저장.
         7) 질의 속도 향상
         8) object column이나 REF column에 대해서는 해당 object에 정의된
         method에 대해 function-based index 생성 가능.
    4. 생성 방법
         CREATE [UNIQUE | BITMAP ] INDEX <index_name>
         ON <tablename> (<index-expression-list>)
         <index-expression-list> -> { <column_name> | <column_expression> }
         예) CREATE INDEX EMP_NAME_INDEX ON EMP (UPPER(ENAME));
         CREATE INDEX EMP_SAL_INDEX ON EMP( SAL + COMM, empno);
         * Function-based index를 생성하기 위해서는 QUERY REWRITE 권한이
         부여 되어 있어야만 한다.
         예) GRANT QUERY REWRITE TO SCOTT;
    5. Function-Based Index 사용을 위한 사전 작업
         1) Function-based index는 cost based optimizer에서만 사용 가능하므로,
         테이블에 대해 미리 analyze 해 주는 것이 바람직하다.
         그리고 init 파일에서 OPTIMIZER_MODE 를 FIRST_ROWS 나 ALL_ROWS 등으
    로 지정하거나 HINT 등을 사용하여 cost based optimizer가 사용되도록
    한다.
         2) init 파일에서 COMPATIBLE 파라미터 값을 8.1 이상으로 설정되어 있어야
    한다.
         ( 예 : COMPATIBLE = 8.1.6 )
         3) session/instance level 에서 QUERY_REWRITE_ENABLED 값이 TRUE 지정
    되어 있어야 한다.
         ( 예 : ALTER SESSION SET QUERY_REWRITE_ENABLED = TRUE; )
    6. 예제
         1) init 파라미터에서 다음과 같이 지정
         compatible = 8.1.6 (반드시 8.1이상이어야 한다)
         query_rewrite_enabled = true
         query_rewrite_integrity = trusted
         2) SCOTT 유저에서 function_based_index 생성
         create index idx_emp_lower_ename
         on emp
         ( lower(ename) ) ;
         3) EMP table analyze
         analyze table emp compute statistics ;
         4) PLAN_TABLE 생성
         @ ?/rdbms/admin/utlxplan.sql
         5) Cost based optimizer 선택
         alter session set optimizer_mode = FIRST_ROWS ;
         6) Query 실행
         explain plan set statement_id='qry1' FOR
         select empno, ename
         from emp
         where lower(ename) = 'ford' ;
         7) PLAN 분석
         SELECT LPAD(' ',2*level-2)||operation||' '||options||' '||object_name query_plan
         FROM plan_table
         WHERE statement_id='qry1'
         CONNECT BY prior id = parent_id
         START WITH id = 0 order by id ;
         -> 결과
         QUERY_PLAN
         SELECT STATEMENT
         TABLE ACCESS BY INDEX ROWID EMP
         INDEX RANGE SCAN IDX_EMP_LOWER_ENAME
    7. 결론
    Function-based index는 적절하게 사용될 경우 성능상의 많은 이점을 가져
    온다. Oracle8i Designing and Tuning for Performance에서도 가능한 한
    Function-based index를 사용하는 것을 권장하고 있으며, LOWER(), UPPER()
    등의 함수를 사용하여 불가피하게 FULL TABLE SCAN을 하는 경우에 대해서도
    효과적으로 처리해 줄 수 있는 방안이라 할 수 있다.
    Reference Documents
    -------------------

    Partha:
    From the Oracle8i Administrators Guide:
    "Table owners should have EXECUTE privileges on the functions used in function-based indexes.
    For the creation of a function-based index in your own schema, you must be
    granted the CREATE INDEX and QUERY REWRITE system privileges. To create
    the index in another schema or on another schemas tables, you must have the
    CREATE ANY INDEX and GLOBAL QUERY REWRITE privileges."
    Hope this helps.
    Peter

  • Performance problem because of ignored index

    Hi,
    We have a performance problem with kodo ignoring indexes in Oracle:
    Our baseclass of all our persistent classes (LogasPoImpl) has a subclass
    CODEZOLLMASSNAHMENIMPL.
    We use vertical mapping for all subclasses and have 400.000 instances of
    CODEZOLLMASSNAHMENIMPL.
    We defined an additional index on an attribute of CODEZOLLMASSNAHMENIMPL.
    A query with a filter like "myIndexedAttribute = 'DE'" takes about 15
    seconds on Oracle 8.1.7.
    Kodo logs something like the following:
    [14903 ms] executing prepstmnt 6156689 SELECT (...)
    FROM CODEZOLLMASSNAHMENIMPL t0, LOGASPOIMPL t1
    WHERE (t0.myIndexedAttribute = ?)
    AND t1.JDOCLASS = ?
    AND t0.JDOID = t1.JDOID
    [params=(String) DE, (String)
    de.logas.zoll.eztneu.CodeZollMassnahmenImpl] [reused=0]
    When I execute the same statement from a SQL-prompt, it takes that long as
    well, but when I swap the tablenames in the from part
    (to "FROM LOGASPOIMPL t1, CODEZOLLMASSNAHMENIMPL t0") the result comes
    immediately.
    I've had a look at the query plans, oracle creates for the two statements
    and found, that our index on myIndexedAttribute is not used
    by the first statement, but it is by the second.
    How can I make Kodo use the faster statement?
    I've tried to use the "jdbc-indexed" tag, but without success so far.
    Thanks,
    Wolfgang

    Thank you very much, Stefan & Alex.
    After computing statistics the index is used and the performance is fine
    now.
    - Wolfgang
    Alex Roytman wrote:
    ANALYZE TABLE MY_TABLE COMPUTE STATISTICS;
    "Stefan" <[email protected]> wrote in message
    news:btlqsj$f18$[email protected]..
    When I execute the same statement from a SQL-prompt, it takes that longas
    well, but when I swap the tablenames in the from part
    (to "FROM LOGASPOIMPL t1, CODEZOLLMASSNAHMENIMPL t0") the result comes
    immediately.
    I've had a look at the query plans, oracle creates for the twostatements
    and found, that our index on myIndexedAttribute is not used
    by the first statement, but it is by the second.
    How can I make Kodo use the faster statement?
    I've tried to use the "jdbc-indexed" tag, but without success so far.I know that in DB2 there is a function called "Run Statistics" which you
    can (and should do) on all tables involved in a query (at least once a
    month, when there are heavy changes in the tables).
    On information gathered by this statistics DB2 can optimize your queries
    and execution path's
    Since I was once involved in query performance optimizing on DB/2 I can
    say you can get improvements of 80% on big tables on which statistics are
    run and not. (Since the execution plans created by the optimizer differ
    heavily)
    Since I'm working now with Oracle as well, at least I can say, that Oracle
    has a featere like statistics as well. (go into the manager enterprise
    Console and click on a table, you will find a row "statisitics last run")
    I don't know how to trigger these statistics nor whether they would
    influence the query execution path on oracle (thus "swapping" tablenames
    by itself), since I didn't have time to do further research on thatmatter.
    But it's worth a try to find out and maybe it helps on you problem ?

Maybe you are looking for

  • ADC from vid card to a VGA 2nd display, out of stock?

    We have an old quicksilver G4 800 mhz tower that a co-worker wants to have a 2nd display attached to. The card has 2 outputs, a VGA and an ADC. About a year ago, I went to our local Apple Reseller (not an apple store) and bought a ADC to VGA adaptor

  • Finder cannot find - marketing showcase only?

    After I got over the theater trailers for finder, I am marveling at its * non * functionality * in doing what I consider some pretty basic tasks. I'm not asking a lot. For one, I would just like to locate my .Pages and .Numbers and Keynote files. Typ

  • I have a macbook pro 15" Retina. I have notifications activated.

    The problem is my friend logged into his twitter account and I now always get notifications for his twitter. How do I delete his account from my notifications?

  • Printed cheque - comma and decimal point

    Hi, My company use pre-printed cheque to make payment. However, there is some error with the printed cheque. When printed, the decimal point and the comma is somehow mixed out.   For example, amount of $1,300.50   -   will appears as $1.300,50 Why is

  • I had to reinstall firefox and now i can't find any of my bookmarks.

    i had to reinstall firefox because i had reset my computer and now i can't find any of my bookmarks. what do i do? i need most of those for college and i don't remember them. i have a windows 8.1 computer and i'm not super teck savvy. i need the answ