Index Unusable

Guys,
I am getting an Index Unusable error. When I check for the status of that respective index it shows as 'unusable'.
Please suggest me if there is any other way by which I can make its status back to 'valid' again
Thanks

One way would be:
ALTER INDEX index_name REBUILD

Similar Messages

  • Dbms_metadata.get_ddl returns unusable create index statement

    Hello everybody,
    I'm trying to write a procdeure that automatically deletes all duplicate record and rebuild all table indexes after an sqlldr load with direct path.
    In short the procdeure indentifies the indexes, read them using dbms_metadata.get_ddl('INDEX', 'IDX_UNIQUE_TEST') drops them, deletes the duplicated records and then recreates the indexes.
    However after the sqlldr, get_ddl function returns the following result:
    CREATE UNIQUE INDEX "MYUSER"."IDX_UNIQUE_TEST" ON "EDWH"."FOREX_ORD_PRC_INTRADAY" "C_ORD_TYP", "C_ORD", "D_INI_VAL", "C_PRC_TYP")
    PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
    STORAGE(INITIAL 131072 NEXT 131072 MINEXTENTS 1 MAXEXTENTS 2147483645
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
    TABLESPACE "MYTABLESPACE"
    ALTER INDEX "MYUSER"."IDX_UNIQUE_TEST"  UNUSABLE
    As you can see there is an ALTER INDEX at the end that makes the whole statement invalid.
    Has anyone already seen that? I've tried to google it but with no chance. Help with this would really be appreciated.
    Thanks in advance
    Ross

    Mmh, yes it is unusable before the get_ddl, but how comes it returns both the create index and the alter index unusable statements?
    I've tried to make the index unusable with the alter index ... unusable statement but get_ddl still returned the create index only.
    I'm guessing that production server (10.2.0.4.0) is behaving differently from test machine (9.2.0.4.0). Any idea on that?
    Ross

  • Using UNUSABLE on Unique Index gives "initially in unusable state" error

    I am doing the following:
    1. Truncate table
    2 Alter PK Index Disable
    2. Alter Unique Index Unusable
    3. Insert /*+ APPEND NOLOGGING*/ into my table
    My problem is, I get an "ORA-26026: unique index ... initially in unusable state" error when I try to do the Insert. If I make the Unique index non-unique it isn't a problem. If I drop the index and recreate it its not a problem - so uniqueness doesn't appear to be the issue. Can you not use UNUSABLE with a Unique index, I couldn't find any reference to this in the 10g docs.
    I am using 10.1.0.4.
    Thanks
    Richard

    26026, 0000, "unique index %s.%s initially in unusable state"
    //* Cause: A unique index is in IU state (a unique index cannot have
    //* index maintenance skipped via SKIP_UNUSABLE_INDEXES).
    //* Action: Either rebuild the index or index partition, or use
    //* SKIP_INDEX_MAINTENANCE if the client is SQL*Loader.

  • ORA-01502: Index or Partition is in unusable status. while truncating table

    Hi All,
    One of our Devlopers compalined that he is getting ORA-01502 : Index or partition is unusable status while truncating the a table in our Dataware house production database. He is using the following commands.
    Alter index <index_name> unusable;
    Truncate table <table_name> ;
    He is running a scripts to truncate each table and ecah time he is passing the table name as an input parameter to script. He is using same method to truncate four tables each having a BITMAP and a REGULAR index. For two tables every thing is working fine, but for other two tables the he is getting ORA-01502 for BITMAP indexes. It a weekly process and every week he is getting the same issue. I checkd the Index status, they are in valid status only.
    For a work around I have created a table with BITMAP and regular index in our dev database. made the indexes unusable, checked their status. I truncated the table. Importent thing here is the Indexes are becoming vaild when I truncate the table.
    I suspect that my devloper's Indexes were already in unusable status (before he use the command ALTER INDEX), when he truncated the table, oracle trying to validate the index and throwing the error ORA-01502 because the Indexes are in unusabel statsu for a while.
    I tried searching for the mechanism of truncate table command and its effect on Indexes. But I did not find any luck, no one is speaking about index when truncating the table. Can any one please help me????
    Sorry for lengthy post. Any help is greatly appriciated and I thank every one in advance.

    DDL for Indexes getting ORA-01502 error
    CREATE BITMAP INDEX DWHMGR.ACT_TXN_LN_STG_01_XN3 ON DWHMGR.ACCT_TXN_LINE_TERM_BAL_STG_01 (TERM_BAL_CD ASC) TABLESPACE "BALFD_INX_04" NOLOGGING PCTFREE 1 INITRANS 2 MAXTRANS 255 STORAGE
    ( INITIAL 8M NEXT 8M MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 BUFFER_POOL DEFAULT );
    CREATE BITMAP INDEX DWHMGR.ACCT_TERM_BAL_STG_01_XN3 ON DWHMGR.ACCT_TERM_BAL_STG_01 TERM_BAL_CD ASC) TABLESPACE "BALFD_INX_04" NOLOGGING PCTFREE 1 INITRANS 2 MAXTRANS 255 STORAGE
    ( INITIAL 8M NEXT 8M MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 BUFFER_POOL DEFAULT );
    Indexes that have no issues.
    CREATE INDEX DWHMGR.ACCT_TERM_BAL_STG_01_XN2 ON DWHMGR.ACCT_TERM_BAL_STG_01 (ACCT_REF_NB ASC) TABLESPACE "BALFD_INX_04" NOLOGGING PCTFREE 1 INITRANS 2 MAXTRANS 255 STORAGE (INITIAL 8M
    NEXT 8M MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 BUFFER_POOL DEFAULT );
    CREATE BITMAP INDEX DWHMGR.ACCT_PRC_STG_01_XN1 ON DWHMGR.ACCT_PRC_STG_01 (ACCT_ORG_CD ASC) TABLESPACE "BALFD_INX_04" NOLOGGING PCTFREE 1 INITRANS 2 MAXTRANS 255 STORAGE ( INITIAL 8M
    NEXT 8M MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 BUFFER_POOL DEFAULT );
    Please look at the DDL of the indexes and let me know if you need any other information.

  • ORA-01502 error in case of unusable unique index and bulk dml

    Hi, all.
    The db is 11.2.0.3 on a linux machine.
    I made a unique index unusable, and issued a dml on the table.
    Howerver, oracle gave me ORA-01502 error.
    In order to avoid ORA-01502 error, do I have to drop the unique index ,and do bulk dml, and recreate the index?
    Or Is there any other solution without re-creating the unique index?
    create table hoho.abcde as
    select level col1 from dual connect by level <=1000
    10:09:55 HOHO@PD1MGD>create unique index hoho.abcde_dx1 on hoho.abcde (col1);
    Index created.
    10:10:23 HOHO@PD1MGD>alter index hoho.abcde_dx1 unusable;
    Index altered.
    Elapsed: 00:00:00.03
    10:11:27 HOHO@PD1MGD>delete from hoho.abcde where rownum < 11;
    delete from hoho.abcde where rownum < 11
    ERROR at line 1:
    ORA-01502: index 'HOHO.ABCDE_DX1' or partition of such index is in unusable stateThanks in advance.
    Best Regards.

    Hi. all.
    The following is from "http://docs.oracle.com/cd/E14072_01/server.112/e10595/indexes002.htm#CIHJIDJG".
    Is there anyone who can show me a tip to avoid the following without dropping and re-creating an unique index?
    •DML statements terminate with an error if there are any unusable indexes that are used to enforce the UNIQUE constraint.
    Unusable indexes
    An unusable index is ignored by the optimizer and is not maintained by DML. One reason to make an index unusable is if you want to improve the performance of bulk loads. (Bulk loads go more quickly if the database does not need to maintain indexes when inserting rows.) Instead of dropping the index and later recreating it, which requires you to recall the exact parameters of the CREATE INDEX statement, you can make the index unusable, and then just rebuild it. You can create an index in the unusable state, or you can mark an existing index or index partition unusable. The database may mark an index unusable under certain circumstances, such as when there is a failure while building the index. When one partition of a partitioned index is marked unusable, the other partitions of the index remain valid.
    An unusable index or index partition must be rebuilt, or dropped and re-created, before it can be used. Truncating a table makes an unusable index valid.
    Beginning with Oracle Database 11g Release 2, when you make an existing index unusable, its index segment is dropped.
    The functionality of unusable indexes depends on the setting of the SKIP_UNUSABLE_INDEXES initialization parameter.
    When SKIP_UNUSABLE_INDEXES is TRUE (the default), then:
    •DML statements against the table proceed, but unusable indexes are not maintained.
    •DML statements terminate with an error if there are any unusable indexes that are used to enforce the UNIQUE constraint.
    •For non-partitioned indexes, the optimizer does not consider any unusable indexes when creating an access plan for SELECT statements. The only exception is when an index is explicitly specified with the INDEX() hint.
    •For a partitioned index where one or more of the partitions are unusable, the optimizer does not consider the index if it cannot determine at query compilation time if any of the index partitions can be pruned. This is true for both partitioned and non-partitioned tables. The only exception is when an index is explicitly specified with the INDEX() hint.
    When SKIP_UNUSABLE_INDEXES is FALSE, then:
    •If any unusable indexes or index partitions are present, any DML statements that would cause those indexes or index partitions to be updated are terminated with an error.
    •For SELECT statements, if an unusable index or unusable index partition is present but the optimizer does not choose to use it for the access plan, the statement proceeds. However, if the optimizer does choose to use the unusable index or unusable index partition, the statement terminates with an error.Thanks in advance.
    Best Regards.

  • Local index vs global index in partitioned tables

    Hi,
    I want to know the differences between a global and a local index.
    I'm working with partitioned tables about 10 millons rows and 40 partitions.
    I know that when your table is partitioned and your index non-partitioned is possible that
    some database operations make your index unusable and you have tu rebuid it, for example
    when yo truncate a partition your global index results unusable, is there any other operation
    that make the global index unusable??
    I think that the advantage of a global index is that takes less space than a local and is easier to rebuild,
    and the advantage of a local index is that is more effective resolving a query isn't it???
    Any advice and help about local vs global index in partitioned tables will be greatly apreciatted.
    Thanks in advance

    here is the documentation -> http://download-uk.oracle.com/docs/cd/B19306_01/server.102/b14220/partconc.htm#sthref2570
    In general, you should use global indexes for OLTP applications and local indexes for data warehousing or DSS applications. Also, whenever possible, you should try to use local indexes because they are easier to manage. When deciding what kind of partitioned index to use, you should consider the following guidelines in order:
    1. If the table partitioning column is a subset of the index keys, use a local index. If this is the case, you are finished. If this is not the case, continue to guideline 2.
    2. If the index is unique, use a global index. If this is the case, you are finished. If this is not the case, continue to guideline 3.
    3. If your priority is manageability, use a local index. If this is the case, you are finished. If this is not the case, continue to guideline 4.
    4. If the application is an OLTP one and users need quick response times, use a global index. If the application is a DSS one and users are more interested in throughput, use a local index.
    Kind regards,
    Tonguç

  • How to maintain bitmap index on a large table in DW?

    Hi all,
    We have many tables which are constantly doing either FULL or INCREMENTAL loading.
    And we have created many BITMAP indexes and several B*Tree index (caused by PRIMARY KEY or UNIQUE key constraints) on those tables.
    So, what I want to know is, how to maintain those BITMAP (and B*Tree) indexes for different loading mode?
    like, should I drop the index before the full load and re-create it after that?
    and do nothing in INCREMENTAL loading? I am aware that it will take more time to load with indexes.
    any links, books, articles or opinions would be highly appreciated.
    Thanks

    Just to reiterate, add to what Adam said. From Oracle Doc
    http://download.oracle.com/docs/cd/E11882_01/server.112/e17120/indexes002.htm#CIHJIDJG
    Unusable indexes
    An unusable index is ignored by the optimizer and is not maintained by DML. One reason to make an index unusable is to improve bulk load performance. (Bulk loads go more quickly if the database does not need to maintain indexes when inserting rows.) Instead of dropping the index and later re-creating it, which requires you to recall the exact parameters of the CREATE INDEX statement, you can make the index unusable, and then rebuild it.
    You can create an index in the unusable state, or you can mark an existing index or index partition unusable. In some cases the database may mark an index unusable, such as when a failure occurs while building the index. When one partition of a partitioned index is marked unusable, the other partitions of the index remain valid.
    An unusable index or index partition must be rebuilt, or dropped and re-created, before it can be used. Truncating a table makes an unusable index valid.
    Beginning with Oracle Database 11g Release 2, when you make an existing index unusable, its index segment is dropped.
    The functionality of unusable indexes depends on the setting of the SKIP_UNUSABLE_INDEXES initialization parameter. When SKIP_UNUSABLE_INDEXES is TRUE (the default), then:
    •DML statements against the table proceed, but unusable indexes are not maintained.
    •DML statements terminate with an error if there are any unusable indexes that are used to enforce the UNIQUE constraint.
    •For nonpartitioned indexes, the optimizer does not consider any unusable indexes when creating an access plan for SELECT statements. The only exception is when an index is explicitly specified with the INDEX() hint.
    •For a partitioned index where one or more of the partitions are unusable, the optimizer does not consider the index if it cannot determine at query compilation time if any of the index partitions can be pruned. This is true for both partitioned and nonpartitioned tables. The only exception is when an index is explicitly specified with the INDEX() hint.
    When SKIP_UNUSABLE_INDEXES is FALSE, then:
    •If any unusable indexes or index partitions are present, any DML statements that would cause those indexes or index partitions to be updated are terminated with an error.
    •For SELECT statements, if an unusable index or unusable index partition is present but the optimizer does not choose to use it for the access plan, the statement proceeds. However, if the optimizer does choose to use the unusable index or unusable index partition, the statement terminates with an error.
    Incremental load really matters the volume and whether for new dats you just add new partitions or subpartitions . If my incremntal go all over place and/or if I am touching few thousand rows. Yes might want to keep the indexes valid and let Oracle maintain it. IF millions added or incremental data just added to new part/subpart . Keeping indexes unsable for those partitions/subpartitions and the rebuilding it later may yield better results.

  • Function Based index getting disabled frequently

    I am facing some error like “ORA-30554: function-based index ORADB1.FUN_INDX1 is disabled” in the development database. I verified that the function which is referred by the index is valid. Once I even got the tedious generic error ORA-600 because of this. I referred the metalink and advised to drop and recreate the index
    Dropping and recreating the index will solve the issue for 2-3 days and again the same will be repeated. So what I did is made the index unusable as it will not affect the other application activities. Can anybody give a clue on this issue?

    I am facing some error like “ORA-30554:
    function-based index ORADB1.FUN_INDX1 is disabled” Cause: An attempt was made to access a function-based index that has been marked disabled because the function on which the index depends has been changed.
    Action: Perform one of the following actions: -- drop the specified index using the DROP INDEX command -- rebuild the specified index using the ALTER INDEX REBUILD command -- enable the specified index using the ALTER INDEX ENABLE command -- make the specified index usable using the ALTER INDEX UNUSABLE command

  • Parallel Index creation takes more time...!!

    OS - Windows 2008 Server R2
    Oracle - 10.2.0.3.0
    My table size is - 400gb
    Number of records - 657,45,95,123
    my column definition first_col varchar2(22) ; -> I am creating index on this column
    first_col -> actual average size of column value is 10
    I started to create index on this column by following command
    CREATE INDEX CALL_GROUP1_ANO ON CALL_GROUP1(A_NO) LOCAL PARALLEL 8 NOLOGGING COMPRESS ;
    -> In my first attempt after three hours I got an error :
    ORA-01652: unable to extend temp segment by 128 in tablespace TEMP
    So I increased the size of temp tablespace to 380GB ,Because i expect the size of first_col index this much.
    -> In my second attempt Index creation is keep going even after 17 hours...!!
    Now the usage of temp space is 162 GB ... still it is growing..
    -> I checked EM Advisor Central ADDM :
    it says - The PGA was inadequately sized, causing additional I/O to temporary tablespaces to consume significant database time.
    1. why this takes this much of Temp space..?
    2. It is required this much of time to CREATE INDEX in parallel processing...? more than 17 hrs
    3. How to calculate and set the size of PGA..?

    OraFighter wrote:
    Oracle - 10.2.0.3.0
    My table size is - 400gb
    Number of records - 657,45,95,123
    my column definition first_col varchar2(22) ; -> I am creating index on this column
    first_col -> actual average size of column value is 10
    I started to create index on this column by following command
    CREATE INDEX CALL_GROUP1_ANO ON CALL_GROUP1(A_NO) LOCAL PARALLEL 8 NOLOGGING COMPRESS ;
    Now the usage of temp space is 162 GB ... still it is growing..The entire data set has to be sorted - and the space needed doesn't really vary with degree of parallelism.
    6,574,595,123 index entries with a key size of 10 bytes each (assuming that in your choice of character set one character = one byte) requires per row approximately
    4 bytes row overhead 10 bytes data, 2 bytes column overhead for data, 6 bytes rowid, 2 bytes column overhead for rowid = 24 bytes.
    For the sorting overheads, using the version 2 sort, you need approximately 1 pointer per row, which is 8 bytes (I assumed you're on 64 bit Oracle on this platform) - giving a total of 32 bytes per row.
    32 * 6,574,595,123 / 1073741824 = 196 GB
    You haven't said how many partitions you have, but you might want to consider creating the index unusable, then issuing a rebuild command on each partition in turn. From "Practical Oracle 8i":
    <blockquote>
    In the absence of partitioned tables, what would you do if you needed to create a new index on a massive data set to address a new user requirement? Can you imagine the time it would take to create an index on a 450M row table, not to mention the amount of space needed in the temporary segment. It's the sort of job that you schedule for Christmas or Easter and buy a couple of extra discs to add to the temporary tablespace.
    With suitably partitioned tables, and perhaps a suitably friendly application, the scale of the problems isn't really that great, because you can build the index on each partition in turn. This trick depends on a little SQL feature that appears to be legal even though I haven't managed to find it in the SQL reference manual:
         create index big_new_index on partitioned_table (colX)
         local
         UNUSABLE
         tablespace scratchpad
    The key word is UNUSABLE. Although the manual states that you can 'alter' an index to be unusable, it does not suggest that you can create it as initially unusable, nevertheless this statement works. The effect is to put the definition of the index into the data dictionary, and allocate all the necessary segments and partitions for the index - but it does not do any of the real work that would normally be involved in building an index on 450M rows.
    </blockquote>
    (The trick was eventually documented a couple of years after I wrote the book.)
    Regards
    Jonathan Lewis

  • 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

  • Local Bitmap Index Confusions

    Hi,
    I am using Oracle 10.2.0.3.0 on Solaris 5.10.
    I have a range based partition table with 60 partitions. This is a fact table. I have to load 60 days data in this table. I have created a partition for each day and the partition key is the date column. I created the table with partition, but didn't create the local bitmap index on the partition key vdate, because as far as I know oracle makes the local bitmap index unusable before the insert and then we have to rebuild it after the load. Is that right?
    So the better strategy is to first load the data in the partition and then create a local bitmap index on that partition, is that right?
    For instance, in future, some rows get inserted in an existing partition where the local bitmap index is present, so then I should once again rebuild the index on that partition, because in case of insert Oracle would have disabled it?
    In this table there is another column vactivity, which is a foreign key from a dimension. Many queries use this column in there where clause. I would also like to create a bitmap index on this column? On this non partitioned key column, the local bitmap index should be created. Is that right?
    Please also suggest as which is more faster, rebuilding a local bitmap index after rendering it unusable, or dropping and recreating it?
    Thanks and best regards

    The more I know, the more I know that how little I know. Thanks Jonathan for a very insightful answer. Please clarify some points and thanks for your valuable feedback.
    Jonathan Lewis wrote:
    Fahd Mirza wrote:
    Hi,
    I am using Oracle 10.2.0.3.0 on Solaris 5.10.
    I have a range based partition table with 60 partitions. This is a fact table. I have to load 60 days data in this table. I have created a partition for each day and the partition key is the date column. I created the table with partition, but didn't create the local bitmap index on the partition key vdate, because as far as I know oracle makes the local bitmap index unusable before the insert and then we have to rebuild it after the load. Is that right?
    That may depend on the software you use to load the data, it's not a necessity from the perspective of the database.I am using Oracle Warehouse Builder to load the data into the database.
    >
    So the better strategy is to first load the data in the partition and then create a local bitmap index on that partition, is that right?
    Depends on the tools, and whether there is data in the table already - but Oracle will optimise index maintenance for bulk inserts in a way which means that it isn't necessary to worry about dropping/recreating if the index already exists and the table is empty.There is no data in the partitions prior to loading.
    You may find that with one index it's more efficient to create the index with a lot of free space (51%, say) and leave it at that while another index works better if you mark unusable and rebuild.
    Would you please elaborate on this point?
    >
    >>
    In this table there is another column vactivity, which is a foreign key from a dimension. Many queries use this column in there where clause. I would also like to create a bitmap index on this column? On this non partitioned key column, the local bitmap index should be created. Is that right?
    Your question raise more questions:
    a) Does this mean you are only going to have a maximum of two bitmap indexes on this fact table with 60 million rows ? That doesn't sound like it's enough indexes.No, I will create local bitmap indexes on other columns too, which are likely to be used in the adhoc queries.
    b) Are you hoping that the vactivity bitmap index will protect you against foreign key locking ? It won't. This (in part) is why people tend to set FK's to disable, novalidate, rely in data warehouses, they want bitmap indexes not btree indexesActually I haven't created the FK constraint.
    d) Going back to the bitmap index on the date - is this column storing values that are date-only, or is it storing "date with time". If it's date-only then you've only got one date per partition and the index is a waste of space and processing overhead.The datatype of the column vdate is number. Actually it is refering to the pk of time dimension, in which we have preloaded the dates for the next ten years. Would the index be a total waste on this column?
    >
    >
    Please also suggest as which is more faster, rebuilding a local bitmap index after rendering it unusable, or dropping and recreating it?
    Here is the table. I have omitted many partitions for the sake of brevity:
    CREATE TABLE CDR
      CLNG_NMBR          NUMBER,
       CL_RFRNC_NMBR      VARCHAR2(100 BYTE),
      DT_KY              NUMBER,
      TM_KY              NUMBER,
      HRLY_KY            NUMBER,
    ACTVTY_KY          NUMBER,
      INS_DT             DATE,
      SRVC_ID            VARCHAR2(100 BYTE),
      MSC_ADRS           VARCHAR2(100 BYTE),
      TRF_ID             NUMBER,
      CL_TYP             NUMBER,
      LCTN_INFRMTN       VARCHAR2(100 BYTE),
      LCTN_KY            NUMBER,
      SRC_CLNG_NMBR      VARCHAR2(50 BYTE),
      ACTVTY_CL_TP       VARCHAR2(100 CHAR)
    PARTITION BY RANGE(DT_KY)
    PARTITION DAY_20DEC2009 VALUES LESS THAN (4153),
    PARTITION DAY_21DEC2009 VALUES LESS THAN (4154),
    PARTITION DAY_22DEC2009 VALUES LESS THAN (4155),
    PARTITION DAY_23DEC2009 VALUES LESS THAN (4156),
    PARTITION DAY_24DEC2009 VALUES LESS THAN (4157),
    PARTITION DAY_25DEC2009 VALUES LESS THAN (4158),
    PARTITION DAY_26DEC2009 VALUES LESS THAN (4159),
    PARTITION DAY_27DEC2009 VALUES LESS THAN (4160),
    PARTITION DAY_28DEC2009 VALUES LESS THAN (4161),
    PARTITION DAY_31DEC2011 VALUES LESS THAN (4894),
    PARTITION DAY_END_PART VALUES LESS THAN (MAXVALUE)
    TABLESPACE cdr
    PCTUSED    0
    PCTFREE    10
    INITRANS   1
    MAXTRANS   255
    STORAGE    (
                INITIAL          80K
                MINEXTENTS       1
                MAXEXTENTS       UNLIMITED
                PCTINCREASE      0
                BUFFER_POOL      DEFAULT
    NOLOGGING
    NOCOMPRESS
    NOCACHE
    NOPARALLEL
    MONITORING;Many many thanks and best regards
    Fahd
    Edited by: Fahd Mirza on Jun 3, 2010 2:00 PM
    Edited by: Fahd Mirza on Jun 3, 2010 2:03 PM

  • Possible to create partitioned index one partition at a time?

    I have a really large partitioned table. Wanted to know if I can create the partitioned index, one partition at a time? Trying to limit the amount of resources required to throw at it. Note this is not a rebuild or reindex operation. This is a brand new index on a multi-terabyte table.
    .. just throwing this out there...
    Thanks for any insights..
    Daryl.

    Daryl E. wrote:
    I have a really large partitioned table. Wanted to know if I can create the partitioned index, one partition at a time? Trying to limit the amount of resources required to throw at it. Note this is not a rebuild or reindex operation. This is a brand new index on a multi-terabyte table.
    You can create the index "unusable", then alter each partition in turn to make it usable.
    The side effects on optimisation and DML may vary with version of Oracle and whether the index is unique or non-unique.
    Regards
    Jonathan Lewis

  • "UPDATE GLOBAL INDEXES"를 사용하여, DDL 처리와 동시에 GLOBAL INDEX를 자동 관리하는 방안

    제품 : ORACLE SERVER
    작성날짜 :
    "UPDATE GLOBAL INDEXES"를 사용하여, DDL 처리와 동시에 GLOBAL INDEX를 자동 관리하는 방안
    ==========================================================================================
    PURPOSE
    이 문서에서는 다음과 같은 사항을 기술한다.
    1. 새로 추가된 기능으로, 테이블 파티션에 대한 DDL 수행시
    지정 가능한 "UPDATE GLOBAL INDEXES" 절에 대한 설명
    2. UPDATE GLOBAL INDEXES를 사용하는 것 보다는 REBUILD INDEX를
    사용하여야 하는 성능상의 고려사항.
    SCOPE
    Oracle Partitioning Option은 8~10g Standard Edition에서는 지원하지
    않는다.
    Explanation
    테스트를 위해 먼저 4개의 테이블을 생성한다.
    1. RANGE partitioned table을 생성한 후 GLOBAL index를 만든다:
    SQL> create table orders (
    2 order_no number,
    3 part_no varchar2(40),
    4 ord_date date
    5 )
    6 partition by range (ord_date)
    7 (partition Q1 values less than (TO_DATE('01-APR-1999','DD-MON-YYYY')),
    8 partition Q2 values less than (TO_DATE('01-JUL-1999','DD-MON-YYYY')),
    9 partition Q3 values less than (TO_DATE('01-OCT-1999','DD-MON-YYYY')),
    10 partition Q4 values less than (TO_DATE('03-JAN-2000','DD-MON-YYYY'))
    11 );
    Table created.
    SQL> create index orders_global_idx
    2 on orders(ord_date)
    3 global partition by range (ord_date)
    4 (partition GLOBAL1 values less than (TO_DATE('01-APR-1999','DD-MON-YYYY')
    5 partition GLOBAL2 values less than (TO_DATE('01-SEP-1999','DD-MON-YYYY')
    6 partition GLOBAL3 values less than (TO_DATE('01-DEC-2000','DD-MON-YYYY')
    7 partition GLOBAL4 values less than (MAXVALUE)
    8 );
    Index created.
    SQL> select substr(index_name,1,20) index_name,
    2 substr(partition_name,1,20) part_name,
    3 status
    4 from dba_ind_partitions
    5 where index_name= 'ORDERS_GLOBAL_IDX' order by partition_name;
    INDEX_NAME PART_NAME STATUS
    ORDERS_GLOBAL_IDX GLOBAL1 USABLE
    ORDERS_GLOBAL_IDX GLOBAL2 USABLE
    ORDERS_GLOBAL_IDX GLOBAL3 USABLE
    ORDERS_GLOBAL_IDX GLOBAL4 USABLE
    SQL> insert into orders values (1,100,TO_DATE('02-FEB-1999','DD-MON-YYYY'));
    2. HASH partitioned table을 생성 한 후 GLOBAL index를 만든다:
    SQL> CREATE TABLE emp_hpart(
    2 empno NUMBER(4) NOT NULL,
    3 ename VARCHAR2(10),
    4 sal NUMBER(7,2))
    5 PARTITION BY HASH(sal)
    6 (PARTITION H1, PARTITION H2, PARTITION H3, PARTITION H4);
    Table created.
    SQL> CREATE INDEX emp_global_HASH_idx ON emp_hpart(ename)
    2 GLOBAL PARTITION BY RANGE (ename)
    3 (PARTITION p1 VALUES LESS THAN ('N') ,
    4 PARTITION p2 VALUES LESS THAN (MAXVALUE));
    Index created.
    SQL> select substr(index_name,1,20) index_name,
    2 substr(partition_name,1,20) part_name,status
    3 from dba_ind_partitions
    4 where index_name= 'EMP_GLOBAL_HASH_IDX' order by partition_name;
    INDEX_NAME PART_NAME STATUS
    EMP_GLOBAL_HASH_IDX P1 USABLE
    EMP_GLOBAL_HASH_IDX P2 USABLE
    SQL> insert into emp_hpart values (1,'AAA',100);
    3. COMPOSITE partitioned table을 생성한 후 GLOBAL index를 만든다:
    SQL> CREATE TABLE emp_composite(
    2 empno NUMBER(4) NOT NULL,
    3 ename VARCHAR2(10),
    4 sal NUMBER(6))
    5 PARTITION BY RANGE(empno)
    6 SUBPARTITION BY HASH(sal) SUBPARTITIONS 4
    7 (PARTITION p1 VALUES LESS THAN (50),
    8 PARTITION p2 VALUES LESS THAN (100),
    9 PARTITION p3 VALUES LESS THAN (150),
    10 PARTITION p4 VALUES LESS THAN (MAXVALUE));
    Table created.
    SQL> CREATE INDEX emp_global_composite_idx ON emp_composite(ename)
    2 GLOBAL PARTITION BY RANGE (ename)
    3 (PARTITION p1 VALUES LESS THAN ('N') ,
    4 PARTITION p2 VALUES LESS THAN (MAXVALUE));
    Index created.
    SQL> select substr(index_name,1,20) index_name,
    2 substr(partition_name,1,20) part_name,status
    3 from dba_ind_partitions
    4 where index_name= 'EMP_GLOBAL_COMPOSITE_IDX' order by
    partition_name;
    INDEX_NAME PART_NAME STATUS
    EMP_GLOBAL_COMPOSITE P1 USABLE
    EMP_GLOBAL_COMPOSITE P2 USABLE
    SQL> insert into emp_composite values (1,'AAA',100);
    4. LIST partitioned table을 생성 한 후 GLOBAL index를 만든다:
    SQL> CREATE TABLE locations (
    2 location_id NUMBER, street_address VARCHAR2(80), postal_code
    CHAR(12),
    3 city VARCHAR2(80), state_province CHAR(2), country_id
    VARCHAR2(20))
    4 PARTITION BY LIST (state_province)
    5 (PARTITION region_east
    6 VALUES ('MA','NY','CT','NH','ME','MD','VA','PA','NJ'),
    7 PARTITION region_west
    8 VALUES ('CA','AZ','NM','OR','WA','UT','NV','CO'),
    9 PARTITION region_south
    10 VALUES ('TX','KY','TN','LA','MS','AR','AL','GA'),
    11 PARTITION region_central
    12 VALUES ('OH','ND','SD','MO','IL','MI',NULL,'IA'));
    Table created.
    SQL> create index loc_global_idx
    2 on locations (state_province)
    3 global partition by range (state_province)
    4 (partition p1 values less than ('NV'),
    5 partition p2 values less than (maxvalue));
    Index created.
    SQL> INSERT INTO locations VALUES
    2 ( 1000,'1297 Via Cola di Rie','00989','Roma',NULL,'IT');
    1 row created.
    SQL> select substr(index_name,1,20) index_name,
    substr(partition_name,1,20)
    2 part_name , status
    3 from dba_ind_partitions
    4 where index_name= 'LOC_GLOBAL_IDX' order by partition_name;
    INDEX_NAME PART_NAME STATUS
    LOC_GLOBAL_IDX P1 USABLE
    LOC_GLOBAL_IDX P2 USABLE
    *** 오라클 8/8i : UPDATE GLOBAL INDEXES 절을 사용하지 않았을 때
    SQL> select substr(index_name,1,20) index_name,
    2 substr(partition_name,1,20) part_name,status
    3 from dba_ind_partitions
    4 where index_name= 'ORDERS_GLOBAL_IDX' order by partition_name;
    INDEX_NAME PART_NAME STATUS
    ORDERS_GLOBAL_IDX GLOBAL1 USABLE
    ORDERS_GLOBAL_IDX GLOBAL2 USABLE
    ORDERS_GLOBAL_IDX GLOBAL3 USABLE
    ORDERS_GLOBAL_IDX GLOBAL4 USABLE
    SQL> ALTER TABLE orders DROP PARTITION q2;
    Table altered.
    SQL> select substr(index_name,1,20) index_name,
    substr(partition_name,1,20)
    2 part_name, status
    3 from dba_ind_partitions
    4 where index_name= 'ORDERS_GLOBAL_IDX' order by partition_name;
    INDEX_NAME PART_NAME STATUS
    ORDERS_GLOBAL_IDX GLOBAL1 UNUSABLE
    ORDERS_GLOBAL_IDX GLOBAL2 UNUSABLE
    ORDERS_GLOBAL_IDX GLOBAL3 UNUSABLE
    ORDERS_GLOBAL_IDX GLOBAL4 UNUSABLE
    => Oracle 9i 이전 버젼에서는, partitioned table의 특정 파티션에 대해
    DDL을 수행하면, 해당 파티션이 비어있는 상태가 아니라면,
    GLOBAL index에 대한 상태를 invalidate 시킨다.
    => Oracle 9i에서 UPDATE GLOBAL INDEXES 절을 수행하면, 테이블의
    파티션에 대한 DDL 작업을 수행하는 동안 GLOBAL INDEX에
    대한 관리 작업을 자동으로 수행하게 된다.
    그러나 일부 작업에 대해서는, 위와 같은 작업이 허용되지
    않는다.
    *** UPDATE GLOBAL INDEXES 절과 ADD PARTITION 절의 동시 사용
    1. RANGE partitioned table:
    SQL> ALTER TABLE orders ADD PARTITION q5
    2 values less than (TO_DATE('03-JUN-2000','DD-MON-YYYY'))
    3 UPDATE GLOBAL INDEXES;
    ALTER TABLE orders ADD PARTITION q5
    ERROR at line 1:
    ORA-30564: Index maintainence clause not allowed for ADD partition to
    RANGE
    partitioned tables
    UPDATE GLOBAL INDEXES 절은 다음 경우에만 사용할 수 있다.
    => HASH partitioned table에 partition 추가
    => Composite partitioned table에 subpartition 추가
    | RANGE partitioned table에 일반적인 방식으로 작업 수행 |
    SQL> ALTER TABLE orders ADD PARTITION q5
    2 values less than (TO_DATE('03-JUN-2000','DD-MON-YYYY'));
    Table altered.
    SQL> @sel
    INDEX_NAME PART_NAME STATUS
    ORDERS_GLOBAL_IDX GLOBAL1 USABLE
    ORDERS_GLOBAL_IDX GLOBAL2 USABLE
    ORDERS_GLOBAL_IDX GLOBAL3 USABLE
    ORDERS_GLOBAL_IDX GLOBAL4 USABLE
    2. HASH partitioned table:
    | UPDATE GLOBAL INDEXES절을 HASH partitioned table 에서 사용 |
    | 하지 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE emp_hpart ADD PARTITION q5
    2 UPDATE GLOBAL INDEXES;
    Table altered.
    SQL> @sel
    INDEX_NAME PART_NAME STATUS
    EMP_GLOBAL_HASH_IDX P1 USABLE
    EMP_GLOBAL_HASH_IDX P2 USABLE
    3. COMPOSITE partitioned table:
    | UPDATE GLOBAL INDEXES 절을 COMPOSITE partitioned table에서 사용 |
    | 하지 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE emp_composite MODIFY PARTITION p1 add subpartition h5
    2 UPDATE GLOBAL INDEXES;
    Table altered.
    SQL> @sel
    INDEX_NAME PART_NAME STATUS
    EMP_GLOBAL_COMPOSITE P1 USABLE
    EMP_GLOBAL_COMPOSITE P2 USABLE
    4. LIST partitioned table
    | LIST partitioned table에 대해서는 일반적인 방법 사용 |
    SQL> alter table locations ADD
    2 partition nomansland values ('XX');
    Table altered.
    SQL> @sel
    INDEX_NAME PART_NAME STATUS
    LOC_GLOBAL_IDX P1 USABLE
    LOC_GLOBAL_IDX P2 USABLE
    *** UPDATE GLOBAL INDEXES 절과 DROP PARTITION절의 동시사용
    1. RANGE partitioned table:
    | UPDATE GLOBAL INDEXES를 RANGE partitioned table에서 사용 |
    | 하지 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE orders DROP PARTITION q2 UPDATE GLOBAL INDEXES;
    Table altered.
    2. HASH partitioned table:
    HASH partitioned table에서는 DROP 명령을 수행할 수 없으며,
    COALESCE를 대신 사용함 (문서 마지막 부분을 참조)
    3. COMPOSITE partitioned table:
    | UPDATE GLOBAL INDEXES를 COMPOSITE partitioned table에서 사용하지|
    | 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE emp_composite DROP PARTITION p2
    2 UPDATE GLOBAL INDEXES;
    Table altered.
    4. LIST partitioned table:
    | UPDATE GLOBAL INDEXES를 LIST partitioned table에서 사용하지 |
    | 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> alter table locations DROP PARTITION
    2 region_south
    3 UPDATE GLOBAL INDEXES;
    Table altered.
    *** UPDATE GLOBAL INDEXES 절과 SPLIT PARTITION 절의 동시 사용
    1. RANGE partitioned table
    | UPDATE GLOBAL INDEXES를 RANGE partitioned table에서 사용 |
    | 하지 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE orders SPLIT PARTITION q3 AT
    2 (TO_DATE('15-SEP-1999','DD-MON-YYYY'))
    3 INTO (PARTITION q3_1, PARTITION q3_2)
    4 UPDATE GLOBAL INDEXES;
    Table altered.
    2. HASH partitioned table
    HASH partitioned table에서는 SPLIT 명령을 수행할 수 없으며,
    ADD를 대신 사용함 (윗 부분에 기술하였음)
    3. COMPOSITE partitioned table
    | UPDATE GLOBAL INDEXES를 COMPOSITE partitioned table에서 사용하지|
    | 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE emp_composite SPLIT PARTITION p2 AT (80)
    2 INTO (PARTITION p2_1, PARTITION p2_2)
    3 UPDATE GLOBAL INDEXES;
    Table altered.
    4. LIST partitioned tables:
    | UPDATE GLOBAL INDEXES를 LIST partitioned table에서 사용하지 |
    | 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> alter table locations SPLIT PARTITION region_east
    2 VALUES ('MA','NJ')
    3 INTO (PARTITION region_east_1, PARTITION region_east_2)
    4 UPDATE GLOBAL INDEXES;
    Table altered.
    *** UPDATE GLOBAL INDEXES 절과 MERGE PARTITION 절의 동시 사용
    1. RANGE partitioned table
    | UPDATE GLOBAL INDEXES를 RANGE partitioned table에서 사용 |
    | 하지 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE orders MERGE PARTITIONS q2, q3 INTO PARTITION q3
    2 UPDATE GLOBAL INDEXES;
    Table altered.
    2. HASH partitioned table
    HASH partitioned table에서는 MERGE 명령을 수행할 수 없으며,
    COALESCE를 대신 사용함 (문서 마지막 부분을 참조)
    3. COMPOSITE partitioned table
    | UPDATE GLOBAL INDEXES를 COMPOSITE partitioned table에서 사용하지|
    | 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE emp_composite MERGE PARTITIONS p1, p2
    2 INTO PARTITION p2
    3 UPDATE GLOBAL INDEXES;
    Table altered.
    4. LIST partitioned table:
    | UPDATE GLOBAL INDEXES를 LIST partitioned table에서 사용하지 |
    | 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> alter table locations MERGE PARTITIONS region_east,region_west
    2 INTO PARTITION region_north
    3 UPDATE GLOBAL INDEXES;
    Table altered.
    *** UPDATE GLOBAL INDEXES 절과 EXCHANGE PARTITION 절의 동시사용
    1. RANGE partitioned tables
    | UPDATE GLOBAL INDEXES를 RANGE partitioned table에서 사용 |
    | 하지 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE orders EXCHANGE PARTITION q3 WITH TABLE t_orders
    2 UPDATE GLOBAL INDEXES;
    Table altered.
    If GLOBAL indexes exist on the TABLE of exchange, they are left UNUSABLE:
    SQL> create index t_orders_global_idx
    2 on t_orders(ord_date)
    3 global partition by range (ord_date)
    4 (partition GLOBAL1 values less than (TO_DATE('01-APR-1999','DD-MON-YYY
    Y')),
    5 partition GLOBAL2 values less than (TO_DATE('01-SEP-1999','DD-MON-YYY
    Y')),
    6 partition GLOBAL3 values less than (TO_DATE('01-DEC-1999','DD-MON-YYY
    Y')),
    7 partition GLOBAL4 values less than (MAXVALUE) );
    Index created.
    SQL> ALTER TABLE orders EXCHANGE PARTITION q3 WITH TABLE t_orders
    2 UPDATE GLOBAL INDEXES;
    Table altered.
    SQL> @sel
    INDEX_NAME PART_NAME STATUS
    T_ORDERS_GLOBAL_IDX GLOBAL1 UNUSABLE
    T_ORDERS_GLOBAL_IDX GLOBAL2 UNUSABLE
    T_ORDERS_GLOBAL_IDX GLOBAL3 UNUSABLE
    T_ORDERS_GLOBAL_IDX GLOBAL4 UNUSABLE
    ORDERS_GLOBAL_IDX GLOBAL1 USABLE
    ORDERS_GLOBAL_IDX GLOBAL2 USABLE
    ORDERS_GLOBAL_IDX GLOBAL3 USABLE
    ORDERS_GLOBAL_IDX GLOBAL4 USABLE
    2. HASH partitioned tables
    | UPDATE GLOBAL INDEXES를 HASH partitioned table에서 사용하 |
    | 지 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE emp_hpart EXCHANGE PARTITION H1 WITH TABLE t_emp_hpart
    2 UPDATE GLOBAL INDEXES;
    Table altered.
    3. COMPOSITE partitioned tables
    SQL> ALTER TABLE emp_composite EXCHANGE PARTITION p1 WITH TABLE t_emp_composi
    te;
    ALTER TABLE emp_composite EXCHANGE PARTITION p1 WITH TABLE t_emp_composite
    ERROR at line 1:
    ORA-14291: cannot EXCHANGE a composite partition with a non-partitioned table
    | UPDATE GLOBAL INDEXES를 COMPOSITE partitioned table에서 사용하지|
    | 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE emp_composite EXCHANGE SUBPARTITION SYS_SUBP286
    2 WITH TABLE t_emp_composite
    3 UPDATE GLOBAL INDEXES;
    Table altered.
    4. LIST partitioned tables:
    | UPDATE GLOBAL INDEXES를 LIST partitioned table에서 사용하지 |
    | 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE locations EXCHANGE PARTITION region_east
    2 WITH TABLE t_locations
    3 UPDATE GLOBAL INDEXES;
    Table altered.
    *** UPDATE GLOBAL INDEXES절과 MOVE PARTITION 절의 동시사용
    1. RANGE partitioned table
    | UPDATE GLOBAL INDEXES를 RANGE partitioned table에서 사용 |
    | 하지 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE orders MOVE PARTITION q3 TABLESPACE example
    2 UPDATE GLOBAL INDEXES;
    Table altered.
    2. HASH partitioned table
    | UPDATE GLOBAL INDEXES를 HASH partitioned table에서 사용 |
    | 하지 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE emp_hpart MOVE PARTITION H1 TABLESPACE example
    2 UPDATE GLOBAL INDEXES;
    Table altered.
    3. COMPOSITE partitioned table
    SQL> ALTER TABLE emp_composite MOVE PARTITION p1 TABLESPACE example;
    ALTER TABLE emp_composite MOVE PARTITION p1 TABLESPACE example
    ERROR at line 1:
    ORA-14257: cannot move partition other than a Range or Hash partition
    SQL> ALTER TABLE emp_composite MOVE PARTITION p1 TABLESPACE example
    2 UPDATE GLOBAL INDEXES;
    ALTER TABLE emp_composite MOVE PARTITION p1 TABLESPACE example
    ERROR at line 1:
    ORA-14257: cannot move partition other than a Range or Hash partition
    4. LIST partitioned table
    | UPDATE GLOBAL INDEXES를 LIST partitioned table에서 사용하지 |
    | 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE locations MOVE PARTITION region_east
    2 TABLESPACE TS_DATA1
    3 UPDATE GLOBAL INDEXES;
    Table altered.
    *** UPDATE GLOBAL INDEXES 절과 TRUNCATE PARTITION 절의 동시 사용
    1. RANGE partitioned tables
    | UPDATE GLOBAL INDEXES를 RANGE partitioned table에서 사용 |
    | 하지 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE orders TRUNCATE PARTITION q3
    2 UPDATE GLOBAL INDEXES;
    Table truncated.
    2. HASH partitioned tables
    | UPDATE GLOBAL INDEXES를 HASH partitioned table에서 사용 |
    | 하지 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE emp_hpart TRUNCATE PARTITION H1
    2 UPDATE GLOBAL INDEXES;
    Table truncated.
    3. COMPOSITE partitioned table
    | UPDATE GLOBAL INDEXES를 COMPOSITE partitioned table에서 사용하지|
    | 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE emp_composite TRUNCATE PARTITION p1
    2 UPDATE GLOBAL INDEXES;
    Table truncated.
    4. LIST partitioned table
    | UPDATE GLOBAL INDEXES를 LIST partitioned table에서 사용하지 |
    | 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE locations TRUNCATE PARTITION region_east
    2 UPDATE GLOBAL INDEXES;
    Table truncated.
    *** UPDATE GLOBAL INDEXES 절과 COALESCE PARTITION 절의 동시사용
    1. RANGE partitioned table
    Range partitioned table에는 coalesce 기능이 지원되지 않음.
    2. HASH partitioned table
    | UPDATE GLOBAL INDEXES를 HASH partitioned table에서 사용 |
    | 하지 않을 경우 global index가 UNUSABLE 상태로 남음 |
    SQL> ALTER TABLE emp_hpart COALESCE PARTITION
    2 UPDATE GLOBAL INDEXES;
    Table altered.
    3. COMPOSITE partitioned table
    Composite partitioned table에 대해서는 coalesce 기능이 지원되지 않음.
    4. LIST partitioned table
    List partitioned table에 대해서는 coalesce 기능이 지원되지 않음.
    *** 성능상의 문제로 인해 UPDATE GLOBAL INDEXES 절을 사용하는 대신
    *** REBUILD INDEX를 사용하여야 할 경우
    UPDATE GLOBAL INDEXES절을 사용할 경우
    1 이전 버전에서는 단순히 invalid 상태로 표시하고 종료되었던 작업이
    인덱스 관리 작업까지 병행해 수행 되므로 partition DDL operation
    작업 수행 시간이 더 오래 걸린다.
    2 DROP, TRUNCATE, EXCHANGE 작업이 더 오래 걸린다. 이전에는 데이터
    딕셔너리상의 정보만을 갱신하는데 반해, UPDATE GLOBAL INDEXES절을
    사용할 경우, partition 내의 모든 row에 대한 scan 작업이 수행
    되기 때문이다.
    3 GLOBAL INDEX에 대한 갱신 작업을 통한 변경 사항이 redo log 및 rollback에
    남게 된다.
    4 row의 갯수가 작을 경우, update global index절을 사용하여 작업하는 것이
    편리하다.
    5 인덱스를 수동으로 rebuild 할 때 까지 애플리케이션 응답 속도가 현격
    하게 저하되는 것을 피할 수 있다.
    INDEX REBUILD를 사용할 경우
    1 전체 인덱스를 rebuild 하면, index가 좀더 효과적으로 구성된다.
    2 인덱스를 rebuild 하면, 사용자가 인덱스에 대한 구성을 수동으로
    변경할 수 있다.
    Example
    Reference Documents
    <Note:139707.1>

  • Index becomes invalid

    Hi,
    11g on linux.
    I have a batch job run from the application end to refresh the table data. The data may be loaded through sql-loader/DML.
    After running of the batch job, some of the indexes becomes unusable state.
    I dont suspect the index becomes invalid due to duplicate records in primary key. Since I'm able to rebuild the index manually.
    I like to investigate from database end what the batch job does and make the indexes unsuable.
    I'm planning to 10046 trace session trace.
    Could you please share your comments, how to take this forward to find the Root Cause of what is actually happening on the objects and makes index unusable.
    Thanks
    KSG
    Edited by: KSG on May 30, 2013 8:03 PM

    KSG wrote:
    Hi,
    11g on linux.
    I have a batch job run from the application end to refresh the table data. The data may be loaded through sql-loader/DML.
    After running of the batch job, some of the indexes becomes unusable state.
    I dont suspect the index becomes invalid due to duplicate records in primary key. Since I'm able to rebuild the index manually.
    I like to investigate from database end what the batch job does and make the indexes unsuable.
    I'm planning to 10046 trace session trace.
    Could you please share your comments, how to take this forward to find what is actually happening on the objects and makes index unusable.
    Thanks
    KSGhttp://www.lmgtfy.com/?q=oracle+index+unusable
    Handle:     KSG
    Status Level:     Explorer (130)
    Registered:     Dec 23, 2008
    Total Posts:     766
    Total Questions:     212 (146 unresolved)
    I extend to you my condolences; since you rarely get your questions answered here.

Maybe you are looking for