Based on a function index

Hi all

Based on a function index are recommended to sql queries slow poor acceleration?


Thank you

Kinz

The only thing that a function index based (FBI) is intended is so you don't lose the use of an index when you call a function in your WHERE (predicate) clause.

Not sure, I would say it was "the only thing"...

How about you, the ability to provide access to a very small percentage of rows that match a certain condition (using DECODE or CASE) effective index?

Tags: Database

Similar Questions

  • Invalidation of the index based on a function because the recompilation

    Hello

    one of our customers has two indices according to the functions that fall under the State "off" in some situations. After looking more closely at the situation, there are some things that my opinion are different from what I expected of a function-based index. Because I am unable to find anything about either on metalink (or I'm not asking the right question) I would appreciate a second opinion of you.

    To keep things simple, I gave an example to illustrate the behavior. I use Oracle 12.1.0.2, although it can also be reproduced on versions 10.2 and 11.2.

    It's my environment and three parameters that I find relevant to the discussion:

    SQL> select banner from v$version;
    
    BANNER
    ----------------------------------------------------------------------------
    
    Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
    PL/SQL Release 12.1.0.2.0 - Production
    CORE    12.1.0.2.0      Production
    TNS for Linux: Version 12.1.0.2.0 - Production
    NLSRTL Version 12.1.0.2.0 - Production
    
    SQL> show parameter remote_dependencies
    
    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ----------
    remote_dependencies_mode             string      TIMESTAMP
    
    SQL> show parameter query_rewrite
    
    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- -------------
    query_rewrite_enabled                string      TRUE
    query_rewrite_integrity              string      enforced
    

    Test case:

    SQL> CREATE OR REPLACE FUNCTION f1 (p_string IN VARCHAR2)
      2  RETURN VARCHAR2
      3  DETERMINISTIC
      4  IS
      5  BEGIN
      6    RETURN lower(p_string);
      7  END f1;
      8  /
    
    Function created.
    
    SQL> CREATE TABLE tmp_t1 (a_string VARCHAR2(10));
    
    Table created.
    
    SQL> INSERT INTO tmp_t1 VALUES ('a');
    
    1 row created.
    
    SQL> COMMIT;
    
    Commit complete.
    
    SQL> CREATE INDEX x1_tmp_t1 ON tmp_t1(f1(a_string));
    
    Index created.
    
    SQL> set linesize 80;
    SQL> column index_name format a10;
    SQL> SELECT index_name, index_type, status, funcidx_status
      2    FROM user_indexes;
    
    INDEX_NAME INDEX_TYPE                  STATUS   FUNCIDX_
    ---------- --------------------------- -------- --------
    X1_TMP_T1  FUNCTION-BASED NORMAL       VALID    ENABLED
    

    We have our table and our based on an index function which basically converts the values to lowercase. From here on things, download a little weird. What happens with the index based on a function if the underlying function is recompiled? I always thought (and which is also stated in the Concepts and the use of function index (Doc ID 66277.1)) that the index would change its status to "disabled". Here is an excerpt of the said Doc ID:

    The index depends on the State of the PL/SQL function. The index can be

    struck down or rendered useless by changes to the function. The index is marked

    People with DISABILITIES, if he is brought to the function or function is re-created.

    The timestamp of the function is used to validate the index.

    To allow the index after it is created, the function if the signature of the

    the function is identical to the front:

    ALTER INDEX ENABLE;

    If the signature of functions is changed, to make the changes effective

    in the index, the index must be renewed to make it valid.

    ALTER INDEX REBUILD.

    It seems that this is not the case, as the index remains valid and activate.

    SQL> alter function f1 compile;
    
    Function altered.
    
    SQL> SELECT index_name, index_type, status, funcidx_status
      2    FROM user_indexes;
    
    INDEX_NAME INDEX_TYPE                  STATUS   FUNCIDX_
    ---------- --------------------------- -------- --------
    X1_TMP_T1  FUNCTION-BASED NORMAL       VALID    ENABLED
    

    OK, explicitly recompiling function F1 single timestamp changed. What if we replace the function completely and we change the output of the function - for example we will switch from a LOWER function to SUPERIOR function in the body of the F1. Again, it is change that I thought would be not only to disable the index based on a function, but also force its reconstruction. At least that is my understanding of the explanation in Doc ID).

    SQL> CREATE OR REPLACE FUNCTION f1 (p_string IN VARCHAR2)
      2  RETURN VARCHAR2
      3  DETERMINISTIC
      4  IS
      5  BEGIN
      6    RETURN UPPER(p_string);
      7  END f1;
      8  /
    
    Function created.
    
    SQL> SELECT index_name, index_type, status, funcidx_status
      2    FROM user_indexes;
    
    INDEX_NAME INDEX_TYPE                  STATUS   FUNCIDX_
    ---------- --------------------------- -------- --------
    X1_TMP_T1  FUNCTION-BASED NORMAL       VALID    ENABLED
    
    

    Should not be. Because of the function "create or replace" F1 never go through a "invalid" phase which may be necessary for index becomes unusable? What about queries on the TMP_T1 table? Does optimizer always uses access index or not? What about the results?

    SQL> EXPLAIN PLAN SET statement_id='s1' FOR
      2  SELECT a_string, f1(a_string) as f1_a_string, f1('a') as f1_literal
      3    FROM tmp_t1
      4   WHERE f1(a_string) = 'a';
    
    Explained.
    
    SQL> SELECT * from table(dbms_xplan.display(statement_id=>'s1'));
    
    PLAN_TABLE_OUTPUT                                                                                                   
    ------------------------------------------------------------------------------------------------------------------------
    Plan hash value: 3133804460                                                                                         
                                                                                                                        
    -------------------------------------------------------------------------------------------------                   
    | Id  | Operation                           | Name      | Rows  | Bytes | Cost (%CPU)| Time     |                   
    -------------------------------------------------------------------------------------------------                   
    |   0 | SELECT STATEMENT                    |           |     1 |  2024 |     2   (0)| 00:00:01 |                   
    |   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| TMP_T1    |     1 |  2024 |     2   (0)| 00:00:01 |                   
    |*  2 |   INDEX RANGE SCAN                  | X1_TMP_T1 |     1 |       |     1   (0)| 00:00:01 |                   
    -------------------------------------------------------------------------------------------------
    

    The index is used by the optimizer, see the results.

    SQL> column f1_a_string format a15;
    SQL> column f1_literal format a15;
    SQL> SELECT a_string, f1(a_string) as f1_a_string, f1('a') as f1_literal
      2    FROM tmp_t1
      3   WHERE f1(a_string) = 'a';
    
    A_STRING   F1_A_STRING     F1_LITERAL
    ---------- --------------- ---------------
    a          a               A
    

    A_STRING = value in the table

    F1_A_STRING = value of f1 (a_string) but the value is not evaluated because it comes from an index, so tiny value (remember, at the time index created the function returned small values)

    F1_LITERAL = value of the function f1 newly evaluated, using literal instead of the value in the table.

    Predicate f1 (a_string) = 'a' should return no rows because no character uppercase is equivalent to "a". Query with f1 (a_string) = 'A' should return a line, but it doesn't.

    SQL> SELECT a_string, f1(a_string) as f1_a_string, f1('a') as f1_literal
      2    FROM tmp_t1
      3   WHERE f1(a_string) = 'A';
    
    no rows selected
    

    Anyone know if this is an expected behavior? And, is it possible to disable the index based on a function whenever the underlying function signature is changed? The parameter query_rewrite_integrity = applied from

    DOC-ID 66277.1 does not seem to do the trick:

    (c) session variables

    ~~~~~~~~~~~~~~~~~~~~

    QUERY_REWRITE_ENABLED (true, false),

    QUERY_REWRITE_INTEGRITY (confidence, forced, stale_tolerated)

    determines the optimizer to use index based on a function with

    expressions using SQL, user defined functions functions.

    TRUST: Oracle allows rewrites using relationships that have

    was declared.

    APPLIED: Oracle ensures and guarantees consistency and integrity.

    STALE_TOLERATED: Oracle allows rewrites using vessels of the relationship not applied.

    Used in the case of materialized views.

    Set session variable cost function optimizer to choose the

    a function-based index

    Kind regards

    SAMO

    From the Manual 11.2 ( https://docs.oracle.com/cd/E11882_01/appdev.112/e41502/adfns_indexes.htm#ADFNS254 )

    "If you change the semantics of a DETERMINISTIC run and recompile, then you must manually rebuild all addicts depending on index and materialized views." Otherwise, they report results for the previous version of the function. »

    This note is not that I made my initial comment well - which was based on an incorrect memory the relationship between function-oriented and autonomous pl/sql functions, so I won't try to explain it. In fact, I went back to Oracle 8i practice to see if something had changed between yesterday and today and found that I had described exactly the behavior that the OP has been seeing. It's the way it is supposed to be.

    Concerning

    Jonathan Lewis

  • Function Index

    I'm reviewing an existing table in a database Oracle 11g and I do not understand a function based index that was created. The syntax is less than

    CREATE INDEX abc. Orders_Date on abc. ORDERS

    (CASE WHERE "ORDER_DATE" IS NOT NULL THEN "ORDER_DATE" ELSE NULL END)

    LOGGING;

    This table has about 90 000 lines with 32 000 values distinct order_date, 3000 lines have order_dates null. When you run a query on this table using the order_date column it makes a full table scan.

    What does this function index based? because I do not see how it adds all the required features

    Thank you

    As others have said, this index is actually right on order_date, however, is a core function so it cannot be used in queries that use CASES WHEN "ORDER_DATE" IS NOT NULL THEN END NO OTHER "ORDER_DATE."

    It is assumed that it might be possible that there is an index on (order_date) but it was found that it was used in the sql queries, which would have preferred to use other indexes. Some queries benefits so maybe that option based function was created as the sql must refer to the phrase exactly, requests that have received have been rewritten and others were left so that they could avoid the new index of the index.

    Of course, if this were the case then maybe you can take a look at your stats.

  • Another key or a function Index Question

    Hello

    I have the following sample tables:
    CREATE THE TABLE1 TABLE:
    (
    NUMBER OF RESOURCE_KEY
    CONSTRAINT TABLE_PK
    KEY ELEMENTARY SCHOOL
    (RESOURCE_KEY)
    )
    /
    CREATE THE TABLE2 TABLE
    (
    RESOURCE2_KEY INTEGER NOT NULL,
    RESOURCE1_KEY INTEGER NOT NULL,
    CONSTRAINT TABLE2_PK
    UNIQUE (RESOURCE2_KEY, RESOURCE1_KEY)
    USING INDEX
    TABLESPACE TRACERT_DATA,
    CONSTRAINT TABLE1_FK1
    FOREIGN KEY (RESOURCE1_KEY)
    REFERENCES TABLE1 (RESOURCE_KEY)
    ON DELETE CASCADE,
    CONSTRAINT TABLE1_FK2
    FOREIGN KEY (RESOURCE2_KEY)
    REFERENCES TABLE1 (RESOURCE_KEY)
    ON DELETE CASCADE
    )
    /
    Insert into TABLE1
    (RESOURCE_KEY)
    Values
    (1) ;
    Insert into TABLE1
    (RESOURCE_KEY)
    Values
    (2) ;
    COMMIT;


    Now comes the tricky part. I want only one of the following inserts to work:
    Insert into TABLE2
    (RESOURCE2_KEY, RESOURCE1_KEY)
    Values
    (1, 2);
    Insert into TABLE2
    (RESOURCE2_KEY, RESOURCE1_KEY)
    Values
    (2: 1);
    COMMIT;


    Any suggestions?

    You can use a single function index based.

    SQL> create table t (x number, y number);
    
    Table created.
    
    SQL> create unique index t_idx on t (greatest(x, y), least(x,y));
    
    Index created.
    
    SQL> insert into t values (2, 1);
    
    1 row created.
    
    SQL> insert into t values (1, 2);
    insert into t values (1, 2)
    *
    ERROR at line 1:
    ORA-00001: unique constraint (TEST.T_IDX) violated
    
    SQL> rollback;
    
    Rollback complete.
    
    SQL> insert into t values (1, 2);
    
    1 row created.
    
    SQL> insert into t values (2, 1);
    insert into t values (2, 1)
    *
    ERROR at line 1:
    ORA-00001: unique constraint (TEST.T_IDX) violated
    
  • Function Index problem.

    Hello

    I have a problem regarding a function function index.

    example:

    TableName: Test

    Column: A, B, C, D

    I create the index on the table, column, a test using a user-defined function.

    If I do a select on the column, he'll be fine. In other words, I'll get the results you want.

    However, if I insert in the table and validation, and I do a query using the 'A' column in the where clause. I don't have any query hits. Its really weird.

    Have you ever experienced this problem? and is there an index of function according to back and donts w.r.t.?

    Thank you.

    MichaelR

    If you use a deterministic function really, it works:

    create or replace function test_fn (p_number number) return number deterministic
    is
      vreturn number := 0;
    begin
      if p_number = 1 then vreturn := 55; end if;
      if p_number = 2 then vreturn := 89; end if;
      return vreturn;
    end;
    

    Or, if you reverse the order of your second inserts (insert the folder before the recording of test1 test2) - it works fine.

    The reason why you get no results is when you insert the file test1 with a = 2, Oracle executes the function and gets no data, so it assumes that the result is NULL and puts in the index. You said Oracle function is deterministic, so he starts from the principle that any time test_fn (2) is called, it retrieves a null response.

  • How to model a view based on a function table

    Hello

    I want to model a view in SQL Developer Data Modeler which is based on a function of painting as:

    table (function (a, b))

    When the function is a function table in pipeline. How is that possible?

    DM 3.3.0.734 SQL version

    Best regards

    Joop

    Hello

    In the Properties dialog box of the view that is displayed when you create the view, you can select the Report Builder queries (on the general page) button.

    In the query designer, you can enter the query text in the box above the buttons OK and apply, cancel, for example
    SELECT * FROM TABLE (FUNCTION (a, b))

    David

  • CBO bug or not, or else develop do not consider the function index

    SQL> create table test_fun_or as select object_id+sysdate id,object_name from        
    
      2  dba_objects;
    
    Table created.
    
    SQL> create index i_test_fun_or on test_fun_or(id,'a') nologging;   
    
    //I don't know why oracle consider it as function index
    
    Index created.
    
    SQL> create index i_test_fun_or_1 on test_fun_or(object_name) nologging;
    
    Index created.
    
    SQL> set autot trace exp
    
    SQL> exec dbms_stats.gather_table_stats(user,'TEST_FUN_OR',estimate_percent=>null,method_opt=>'for all columns size 1');
    
     
    
    PL/SQL procedure successfully completed.
    
     
    
    SQL> select * from test_fun_or where id=sysdate or object_name='aa';
    
     
    
    Execution Plan
    
    ----------------------------------------------------------
    
    Plan hash value: 3247456674
    
     
    
    ---------------------------------------------------------------------------------
    
    | Id  | Operation         | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
    
    ---------------------------------------------------------------------------------
    
    |   0 | SELECT STATEMENT  |             |     3 |    87 |   219   (3)| 00:00:03 |
    
    |*  1 |  TABLE ACCESS FULL| TEST_FUN_OR |     3 |    87 |   219   (3)| 00:00:03 |
    
    ---------------------------------------------------------------------------------
    
     
    
    Predicate Information (identified by operation id):
    
    ---------------------------------------------------
    
     
    
       1 - filter("OBJECT_NAME"='aa' OR "ID"=SYSDATE@!)
    
     
    
    SQL> select /*+ use_concat */ * from test_fun_or where id=sysdate or object_name='aa'; 
    
    //or expand don't use index i_test_fun_or
    
     
    
    Execution Plan
    
    ----------------------------------------------------------
    
    Plan hash value: 3161566054
    
     
    
    ------------------------------------------------------------------------------------------------
    
    | Id  | Operation                    | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
    
    ------------------------------------------------------------------------------------------------
    
    |   0 | SELECT STATEMENT             |                 |     3 |    87 |   224   (3)| 00:00:03 |
    
    |   1 |  CONCATENATION               |                 |       |       |            |          |
    
    |*  2 |   TABLE ACCESS FULL          | TEST_FUN_OR     |     1 |    29 |   219   (3)| 00:00:03 |
    
    |*  3 |   TABLE ACCESS BY INDEX ROWID| TEST_FUN_OR     |     2 |    58 |     5   (0)| 00:00:01 |
    
    |*  4 |    INDEX RANGE SCAN          | I_TEST_FUN_OR_1 |     2 |       |     3   (0)| 00:00:01 |
    
    ------------------------------------------------------------------------------------------------
    
     
    
    Predicate Information (identified by operation id):
    
    ---------------------------------------------------
    
     
    
       2 - filter("ID"=SYSDATE@!)
    
       3 - filter(LNNVL("ID"=SYSDATE@!))
    
       4 - access("OBJECT_NAME"='aa')
    
     
    
    SQL> drop index i_test_fun_or;
    
     
    
    Index dropped.
    
     
    
    SQL> create index i_test_fun_or on test_fun_or(id,object_name) nologging;
    
     
    
    Index created.
    
     
    
    SQL> alter table test_fun_or modify object_name not null;
    
     
    
    Table altered.
    
     
    
    SQL> select /*+ use_concat */ * from test_fun_or where id=sysdate or object_name='aa';
    
     
    
    Execution Plan
    
    ----------------------------------------------------------
    
    Plan hash value: 1705821130
    
     
    
    ------------------------------------------------------------------------------------------------
    
    | Id  | Operation                    | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
    
    ------------------------------------------------------------------------------------------------
    
    |   0 | SELECT STATEMENT             |                 |     3 |    87 |     8   (0)| 00:00:01 |
    
    |   1 |  CONCATENATION               |                 |       |       |            |          |
    
    |*  2 |   INDEX RANGE SCAN           | I_TEST_FUN_OR   |     1 |    29 |     3   (0)| 00:00:01 |
    
    |*  3 |   TABLE ACCESS BY INDEX ROWID| TEST_FUN_OR     |     2 |    58 |     5   (0)| 00:00:01 |
    
    |*  4 |    INDEX RANGE SCAN          | I_TEST_FUN_OR_1 |     2 |       |     3   (0)| 00:00:01 |
    
    ------------------------------------------------------------------------------------------------
    
     
    
    Predicate Information (identified by operation id):
    
    ---------------------------------------------------
    
        2 - access("ID"=SYSDATE@!)
    
       3 - filter(LNNVL("ID"=SYSDATE@!))
    
       4 - access("OBJECT_NAME"='aa')

    Jinyu wrote:
    Thanks Jonathan, I don't have 11.2.0.2 on-site, I'll test it later, I just test it on 11.2.0.1

    If you see the notes of fixed a bug fixes for 11.2.0.2 Group (Doc ID:1179583.1) it's bug 8352378 "allow index GOLD-Expansion functions.

    Concerning
    Jonathan Lewis

  • the problem of reuse based on the functions

    I read the text in quotes as follows a book written by a Microsoft Developer. I googled and found a good number of citations of it, but did not find any explanation.

    ============
    With languages like C, the basic unit of re-use is the function. The problem with reuse based on a function, is that the function is coupled to the data, he manipulates. and if the data world, a change to a function in the context of re-use infringes another function used somewhere else.
    ============

    C using the libraries widely, which is to reuse based on functions. Kindly can anyone give me a scenario where this problem occurs?

    Java is usually based on objects for reuse, and I confess that my question is not a Java. But I think that would help to better understand the concept or the benefits of the Java language design. So, thank you for allowing me to ask this question here,

    Published by: 799160 on September 30, 2010 12:38

    Published by: 799160 on September 30, 2010 12:57

    That's what I came to read the quote you posted:

    I guess something like the following might happen:

    You (being a person in General) have received a class change. You examine the code for the first time, and it has a bunch of methods and variables of class in it. Some methods use class variables. How can you be sure that if you change the functionality for editing a class variable in one method will not affect the other methods when they are used? This problem can be solved by learning everything that is and how it interacts, the correct way to use it. But then again, if you don't think about it and to make changes... Oops!

    -----

    Maybe another abstract example would be wise:
    Imagine a calculator that could be used by 2 people at the same time? I bet it would come with a few funny answers :)

    -----

    I hope that I wrote a short example of this, he makes some sense:

    public class SuperBigProgram
    {
         private int globalVar;
    
         public static void main ( String[] args )
         {
              new SuperBigProgram();
         }
    
         public SuperBigProgram()
         {
              System.out.println("I'm a super big program.");
    
              globalVar = 0;
    
              //Let's pretend these series of events occur during the program:
    
              doItHighChanceActivity(); //1
              doItHighChanceActivity(); //2
              doItHighChanceActivity(); //3
    
              //Whoops super rare event occured!
              doesNotHappenALot();
    
              doItHighChanceActivity(); //4????    but is really 5.
         }
    
         /**
          * This happens A LOT!
          */
         private void doItHighChanceActivity ()
         {
              superUtilityMethod();
    
              System.out.println("globalVar: " + globalVar);
         }
    
         /**
          * This utility method does some awesome utility stuff for our Super Big Program.
          * This changes some global data.
          */
         private void superUtilityMethod()
         {
              globalVar++;
         }
    
         /**
          * This does not happen a lot, if at all.
          */
         private void doesNotHappenALot()
         {
              //Hey I don't happen a lot but I'm reusing this really cool utility method that contains global data...
              //Code reuse for the win!
              superUtilityMethod();
         }
    
    }
    

    Here is the result:

    I'm a great big program.
    globalVar: 1
    globalVar: 2
    globalVar: 3
    globalVar: 5

    Published by: kilosi on Sep 30, 2010 13:22

  • Graph based on the function of PL/SQL returning the sql query

    Hello, is it possible to have a chart based on PL/SQL return SQL function as with the reports.
    If I need to present data that is based on the graph and the graph itself, and the report is based on the function PL/SQL, SQL back then how I do the table if this is not possible? Also, is there a way to specify which columns in the report to use for the chart instead of having to specify the same question again on the list - this seems a bit redundant.

    Ah, OK - one HTML table does not offer the possibility of using the PL/SQL (I don't know why, if)

    However, you can create a collection (using the APEX_COLLECTION. Function CREATE_COLLECTION_FROM_QUERY) from your vSQL of string and then basing the chart on that?

    Andy

  • How to create indexes based for TO_CHAR function

    I need to create an index of feature based for the to_char.when function I tried, I got an error, "only pure function can be indexed".which the error really means, help me in the creation of the index in order to reduce my query cost.

    It works fine on my database. version 9iR2

    create index IDX_TO_CHAR on emp(to_char(hiredate,'YYYY-MM-DD HH24:MI:SS'));
    
    explain plan for
    select hiredate from emp where to_char(hiredate,'YYYY-MM-DD HH24:MI:SS')='1981-05-01 00:00:00';
    
    ---------------------------------------------------------------------------------
    | Id  | Operation                   |  Name        | Rows  | Bytes | Cost (%CPU)|
    ---------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |              |     1 |     8 |     2  (50)|
    |   1 |  TABLE ACCESS BY INDEX ROWID| EMP          |     1 |     8 |     2  (50)|
    |*  2 |   INDEX RANGE SCAN          | IDX_TO_CHAR  |     1 |       |     2  (50)|
    ---------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access(TO_CHAR("EMP"."HIREDATE",'YYYY-MM-DD HH24:MI:SS')='1981-05-01 00
                  :00:00')
    

    Your not seem to be a setting issue, then why not give us your sql and execution plan and so on.
    There may be other ways to solve your sql as the creation of a function based index?

  • Syntax for the existing index based on a function

    Hello:

    I'm on 10.2.0.3.

    Below is the list of indexes and the columns in the index on one of the tables. Aparantly one of the columns (SYS_NC00220$) is actually a function-based index.

    Anyone know how to get the SQL syntax for this index? TIA.

    INDEX_NAME UNIQUENES COLUMN_NAME POSITION_COLONNE
    ------------------------------ --------- ------------------------------ ---------------
    PS0BI_HDR not BILL_TO_CUST_ID 1
    PS0BI_HDR don't BUSINESS_UNIT 2
    PS0BI_HDR only SYS_NC00220$ 3
    PS1BI_HDR not BILL_STATUS 1
    PS1BI_HDR don't BUSINESS_UNIT 2
    PS1BI_HDR only SYS_NC00220$ 3
    PS2BI_HDR not CONTRACT_NUM 1
    PS2BI_HDR don't BUSINESS_UNIT 2
    PS2BI_HDR only SYS_NC00220$ 3
    NON-UNIQUE PSABI_HDR BILL 1
    PSABI_HDR don't BILL_TO_CUST_ID 2
    PSABI_HDR don't BUSINESS_UNIT 3
    PSABI_HDR not BILL_STATUS 4
    UNIQUE PROCESS_INSTANCE PSBBI_HDR 1
    UNIQUE BUSINESS_UNIT PSBBI_HDR 2
    INVOICE SINGLE PSBBI_HDR 3
    UNIQUE BUSINESS_UNIT PS_BI_HDR 1
    UNIQUE SYS_NC00220 PS_BI_HDR $ 2

    query user_ind_expressions and search for COLUMN_EXPRESSION.

    This will give you an expression.

  • Function index in Oracle

    Hi gurus,

    Just trying to get some info in the function-based index.

    Can we have index created in the user-defined function?

    Lets say we have a table and I need a counter of a column. Could we have indexes on County?

    Select count (name) of employee

    WHERE name = "Hary";

    Thank you

    Tina

    The functions used in the function-based index must be DETERMINISTIC.

    Example you is not deterministic, that is given the input, the output can vary, because there might be 10 Harys today and 5 tomorrow.

    Deterministic functions always return the same value for the same entry.

    See: http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/function.htm#LNPLS1580

  • Function index and virtual columns

    I just read the documentation of Oracle on the FBI. In the context of optimization with a function-based index, it is said that "a virtual column is useful for speed of access to data from expressions.". Here is the link Index-Organized Tables and indexes.

    My question is, does Oracle already not create a virtual column when we create a function-based index?

    Concerning

    Charlie

    Hi Charlie
    Yes, the database engine creates a virtual column. But this column is hidden. Reproduced in 11.2.0.3 example:
    SQL> CREATE TABLE t (n NUMBER);SQL> CREATE INDEX i ON t (round(n,0));
    SQL> SELECT column_name, hidden_column, virtual_column  2  FROM user_tab_cols
      3  WHERE table_name = 'T';
    
    COLUMN_NAME                    HIDDEN VIR
    ------------------------------ ------ ---
    N                              NO    NO
    SYS_NC00002$                  YES    YES
    

    HTH

    Chris Antognini

    Troubleshooting performance Oracle, Apress 2008/2014

  • Function index and user_tab_cols

    Why an entry is created in user_tab_cols when we create a function based on a column in a table?

    create table t1(a varchar2(100), b number); 

    select * from user_tab_cols where table_name = 'T1'; -- Two rows coming 

    create index idx1 on t1(upper(a));

    select * from user_tab_cols where table_name = 'T1'; -- Three rows coming

    What is the reason to put an entry in user_tab_cols?

    Martin Preiss wrote:

    If I remember correctly there is also a VIRTUAL_COLUMN attribute in % _TAB_COLS (at least since 11.1).

    Yes, there is, but how it would be useful to determine if the column is the index of based function related? All not stored in the disk column is a virtual column:

    SQL > create table (tbl)
    Number 2,
    3 the number n
    4                  )
    5.

    Table created.

    SQL > create index tbl_idx1 on tbl (abs (n));

    The index is created.

    SQL > alter table tbl
    2. Add n_ceil number generated always as (ceil (n));

    Modified table.

    SQL > alter table tbl change invisible n_ceil;

    Modified table.

    SQL > create index tbl_idx2 on tbl (n_ceil);

    The index is created.

    SQL > select column_id,.
    2 column_name
    virtual_column 3,.
    4 hidden_column
    5 to user_tab_cols
    6 where table_name = "TBL";

    COLUMN_ID COLUMN_NAME HIDDEN VIR
    ---------- ------------------------------ --- ---
    1 ID                             NO  NO
    2 N                              NO  NO
    SYS_NC00003$ YES YES
    N_CEIL YES YES

    SQL >

    As you can see, the two SYS_NC00003$ and N_CEIL are hidden, virtual columns. This part is the same regardless of the version. And in 12 c with the invisible support of solumn, you can't count on the id of null column. That's why (or at least one of the reasons) Oracle introduced another column in the view _TAB_COLS in 12 c - USER_GENERATED:

    SQL > select column_id,.
    2 column_name
    virtual_column 3,.
    hidden_column 4,.
    5 user_generated
    user_tab_cols 6
    7 where table_name = "TBL";

    COLUMN_ID COLUMN_NAME VIR HID USE
    ---------- ------------------------------ --- --- ---
    1 NOT ONLY ID YES
    2 N NO NO YES
    SYS_NC00003$ YES YES NO
    N_CEIL YES YES YES

    SQL >

    Now, we can say column SYS_NC00003$ is related FBI.

    SY.

  • where to find info on the function index according to

    Hello

    With the help of Oracle 11.2, can someone tell me where I can find information about existing indexes to function in my database?

    I want to shrink the unused space on a table, but there is an index FB I have to drop in order to shrink the space.
    Then I need to recreate it after that I have shrink space.
    But how do I know what the index is created to be used for functions?

    I've looked dba_indexes and dba_ind_expressions with no luck.
    I see the index, but I don't see what functions are which are applied for the FB index.


    Thanks in advance.

    958713 wrote:

    select OWNER, INDEX_NAME, INDEX_TYPE, TABLE_OWNER, TABLE_NAME
    from dba_indexes where index_name = 'TQR1_C3';
    
    OWNER      INDEX_NAME INDEX_TYPE                  TABLE_OWNER  TABLE_NAME
    ---------- ---------- --------------------------- ------------ ----------
    TQ         TQR1_C3    FUNCTION-BASED NORMAL       TQ           TQR1
    

    Now, let's view the selection of dba_ind_expressions...

    INDEX_OWNER  INDEX_NAME TABLE_OWNER  TABLE_NAME COLUMN_EXPRESSI COLUMN_POSITION
    ------------ ---------- ------------ ---------- --------------- ---------------
    TQ           TQR1_C3    TQ           TQR1       "C3"                          1
    

    If you have a top-down column in an index the index is reported "based on a normal function", but the expression simply contains the name of the column without mentioning the bit downward. So one possibility is that your index finger is (descendant of c3).

    Concerning
    Jonathan Lewis

Maybe you are looking for