BITMAP indexes ignored with large IN(...)

I have a fact table with 20 million records joined to a few dimension tables using 10g BITMAP INDEXes but if I add more than two or three items to my SELECT query the optimizer does not choose to use the bitmaps. For example, the first query
SELECT p.period_date, po.agent_id, count(*), SUM(ah.charge_amt)
FROM Travel_History ah, Period p, Agent po
WHERE ah.primary_agent_key = po.agent_key
AND ah.period_key = p.period_key
AND po.agent_id IN( 'DGF ', '001MG ' )
AND p.period_date =
TO_DATE( '20010701', 'YYYYMMDD' )
AND p.period_date =
TO_DATE( '20010801', 'YYYYMMDD' )
GROUP BY po.agent_id, p.period_date
definitely uses my BITMAPs as I see that in my EXECUTION PLAN (i.e. I have set autotrace on):
| 0 | SELECT STATEMENT | | 1 | 32
| 1 | HASH GROUP BY | | 1 | 32
|* 2 | FILTER | | |
| 3 | NESTED LOOPS | | 1 | 32
|* 4 | HASH JOIN | | 1 | 19
|* 5 | TABLE ACCESS FULL | PERIOD | 1 | 10
| 6 | TABLE ACCESS BY INDEX ROWID | TRAVEL_HISTORY | 4000K| 34
| 7 | BITMAP CONVERSION TO ROWIDS | | |
| 8 | BITMAP AND | | |
| 9 | BITMAP OR | | |
|* 10 | BITMAP INDEX SINGLE VALUE| XIF4TRAVEL_HISTORY | |
|* 11 | BITMAP INDEX SINGLE VALUE| XIF4TRAVEL_HISTORY | |
| 12 | BITMAP MERGE | | |
|* 13 | BITMAP INDEX RANGE SCAN | TRVLHIST_MULTI3_BMIX | |
|* 14 | BITMAP INDEX SINGLE VALUE | XIF1TRAVEL_HISTORY | |
|* 15 | TABLE ACCESS BY INDEX ROWID | AGENT | 1 | 13
|* 16 | INDEX UNIQUE SCAN | XPKAGENT | 1 |
There are only a few hundred records for those two dates, and the above query returns in
less than a second.
However, if I replace the two "period_date =" with IN(...) as:
SELECT /*+ INDEX_COMBINE( Travel_history
AcctHist_MULTI3_bmix
XIF4TRAVEL_HISTORY
XIF1TRAVEL_HISTORY )
p.period_date, po.agent_id, count(*), SUM(ah.charge_amt)
FROM Travel_History ah, Period p, Agent po
WHERE ah.primary_agent_key = po.agent_key
AND ah.period_key = p.period_key
AND po.agent_id IN( 'DGF ', '001MG ' )
AND p.period_date IN (
TO_DATE( '20010701', 'YYYYMMDD' ),
TO_DATE( '20010801', 'YYYYMMDD' ) )
GROUP BY po.agent_id, p.period_date
the execution plan goes back to
| 0 | SELECT STATEMENT | | 747 | 23904 | 45760 (7)|
| 1 | HASH GROUP BY | | 747 | 23904 | 45760 (7)|
|* 2 | FILTER | | | | |
|* 3 | HASH JOIN | | 5000K| 152M| 44897 (5)|
| 4 | MERGE JOIN CARTESIAN| | 860 | 19780 | 26 (0)|
|* 5 | TABLE ACCESS FULL | PERIOD | 4 | 40 | 6 (0)|
| 6 | BUFFER SORT | | 215 | 2795 | 20 (0)|
| 7 | TABLE ACCESS FULL | AGENT | 215 | 2795 | 5 (0)|
| 8 | TABLE ACCESS FULL | TRAVEL_HISTORY | 20M| 171M| 44527 (4)|
If I do a UNION with two SELECTs each with a unique period then the BITMAPs get used. I don't get it.
Is there any reason this would be happening???

There are no bitmap indexes, there is a 64k tablespace header block containing the bitmap of occupied and free extents.
Sybrand Bakker
Senior Oracle DBA

Similar Messages

  • 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.

  • Loosing indexes working with large amounts of data

    SCENARIO
    We are working on an Interface project with ORACLE 10g that works basically like this:
    We have some PARAMETER TABLES in which the key users can insert, update or delete parameters via a web UI.
    There is a download process that brings around 20 million records from our ERP system into what we call RFC TABLES. There are around 14 RFC TABLES.
    We developed several procedures that process all this data against the PARAMETER tables according to some business rules and we end up with what we call XML TABLES because they are sent to another software, completing the interface cycle. We also have INTERMIDIATE TABLES that are loaded in the middle of the process.
    The whole process takes around 2 hours to run.
    We had to create several indexes to get to this time. Without the indexes the process will take forever.
    Every night the RFC, INTERMIDIATE and XML tables need to be truncated and then loaded again.
    I know It might seem strange why we delete millions of records and then load them again. The reason is that the data the users insert in the PARAMETER TABLES need to be processed against ALL data that comes from the ERP and goes to the other software.
    PROBLEMS
    As I said we created several indexes in order to make the process run in less than 2 hours.
    We were able to run the whole process in that time for a few times but, suddenly, the process started to HANG forever and we realized some indexes were just not working anymore.
    When running EXPLAIN we figured the indexes were making no effect and we had some ACCESS FULLS. Curiously when taking the HINTS off and putting them back in the indexes started working again.
    SOLUTION
    We tried things like
    DBMS_STATS.GATHER_SCHEMA_STATS(ownname => SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA'), cascade=>TRUE);
    dbms_utility.analyze_schema
    Dropping all tables and recreating the every time before the process starts
    Nothing solved our problem so far.
    We need advice from someone that worked in a process like this. Where millions of records are deleted and inserted and where a lot of indexes are needed.
    THANKS!
    Jose

    skynyrd wrote:
    I don't know anything about
    BIND variables
    Stored Outlines
    bind peeking issue
    or plan stability in the docs
    but I will research about all of them
    we are currently running the process with a new change:
    We put this line:
    DBMS_STATS.GATHER_SCHEMA_STATS(ownname => SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA'), cascade=>TRUE);
    after every big INSERT or UPDATE (more than 1 million records)
    It is running well so far (it's almost in the end of the process). But I don't know if this will be a definitive solution. I hope so.
    I will post here after I have an answer if it solved the problem or not.
    Thanks a lot for your help so farWell, you best get someone in there that knows what those things are, basic development, basic performance tuning and basic administration all are predisposed on understanding these basic concepts, and patching is necessary (unless you are on XE). I would recommend getting books by Tom Kyte, he clearly explains the concepts you need to know to make things work well. You ought to find some good explanations of bind peeking online if you google that term with +Kyte.  
    You will be subject to this error at random times if you don't find the root cause and fix it.
    Here is some food for your thoughts:
    http://structureddata.org/2008/03/26/choosing-an-optimal-stats-gathering-strategy/ (one of those "what to expect from the 10g optimizer" links does work)
    http://kerryosborne.oracle-guy.com/2009/03/bind-variable-peeking-drives-me-nuts/
    http://pastebin.com/yTqnuRNN
    http://kerryosborne.oracle-guy.com/category/oracle/plan-stability/
    Getting stats on the entire schema as frequently as you do may be overkill and time wasting, or even counterproductive if you have an issue with skewed stats. Note that you can figure out what statistics you need and lock them, or if you have several scenarios, export them and import them as necessary. You need to know exactly what you are doing, and that is some amount of work. It's not magic, but it is math. Get Jonathan Lewis' optimizer book.

  • Bitmap indexes

    hi everyone,
    There is table t
    and there are several bitmap one-column indexes
    i1 on t(c1)
    i2 on t(c2)
    i3 on t(c3)
    Column C1 is not nullable.
    Columns C2 and C3 is nullable.
    There is query
    select /*+ index_combine(t) */
      from t
    where c1 = :1
       and c2 in (:2, 'X')
       and c3 = :3
    | Id  | Operation                     |
    |   0 | SELECT STATEMENT              |
    |   1 |  TABLE ACCESS BY INDEX ROWID  |
    |   2 |   BITMAP CONVERSION TO ROWIDS |
    |   3 |    BITMAP AND                 |
    |   4 |     BITMAP INDEX SINGLE VALUE |
    |   5 |     BITMAP INDEX SINGLE VALUE |
    |   6 |     BITMAP OR                 |
    |   7 |      BITMAP INDEX SINGLE VALUE|
    |   8 |      BITMAP INDEX SINGLE VALUE|
    ---------------------------------------Fine.
    But if I create following indexes (and drop previous)
    create bitmap index idx1 on t(C1, C2);
    create bitmap index idx2 on t(C1, C3);
    then the plan of the query above is following:
    | Id  | Operation                    |
    |   0 | SELECT STATEMENT             |
    |   1 |  TABLE ACCESS BY INDEX ROWID |
    |   2 |   BITMAP CONVERSION TO ROWIDS|
    |   3 |    BITMAP INDEX SINGLE VALUE |
    --------------------------------------And the question:
    why the plan does not consist BITMAP AND ?
    Is it possible to scan both new indexes in the query with BITMAP AND?
    Thanks

    793769 wrote:
    Jonathan Lewis wrote:
    I think this means there's a hole in the optimizer's legal strategies that you might have to fill by other methods.Do I right understand that it is impossible to combine bitmap non-one-column indexes?No, you're generalising from the particular - thus are myths created.
    I have demonstrated a case where two bitmap indexes start with the same column+, and the optimizer therefore refuses to do a "bitmap and" between these two indexes when you have where clause that uses equality on the common first column and equalities on the seperate second columns. This is a very small subset of query patterns involving combinations of "non-one-column" (multi-column) indexes.
    For example - why don't you try recreating your (c1, c3) index as (c3, c1) to see what the optimizer can do ?
    In my example it produced the following path:
    | Id  | Operation                    | Name    | Rows  | Bytes | Cost  |
    |   0 | SELECT STATEMENT             |         |    10 |  1250 |     6 |
    |   1 |  TABLE ACCESS BY INDEX ROWID | T1      |    10 |  1250 |     6 |
    |   2 |   BITMAP CONVERSION TO ROWIDS|         |       |       |       |
    |   3 |    BITMAP AND                |         |       |       |       |
    |*  4 |     BITMAP INDEX SINGLE VALUE| T1_B1B2 |       |       |       |
    |   5 |     BITMAP MERGE             |         |       |       |       |
    |*  6 |      BITMAP INDEX RANGE SCAN | T1_B3B1 |       |       |       |
    Predicate Information (identified by operation id):
       4 - access("C1"=5 AND "C2"=50)
       6 - access("C3"=50)
           filter("C3"=50)So it is combining two multi column indexes - but it doesn't appear to be able to use the common column twice to make the second index access as efficient as possible. (This plan appeared for 10.2.0.3 and 11.2.0.2).
    Regards
    Jonathan Lewis

  • Select count from large fact tables with bitmap indexes on them

    Hi..
    I have several large fact tables with bitmap indexes on them, and when I do a select count from these tables, I get a different result than when I do a select count, column one from the table, group by column one. I don't have any null values in these columns. Is there a patch or a one-off that can rectify this.
    Thx

    You may have corruption in the index if the queries ...
    Select /*+ full(t) */ count(*) from my_table t
    ... and ...
    Select /*+ index_combine(t my_index) */ count(*) from my_table t;
    ... give different results.
    Look at metalink for patches, and in the meantime drop-and-recreate the indexes or make them unusable then rebuild them.

  • How does OWB deal with bitmap indexes when inserting?

    How does OWB 9.2 deal with bitmap indexes on a fact table when records are inserted from a staging table? It seems to me that they are left on the table, while in the 9i Server manuals it says that one should not perform heavy DML in this case, because this slows down the inserts considerably and the indexes can get bloated. Should one define a premapping and postmapping process for removal and recreation of the bitmap indexes?
    How handles OWB bitmap indexes in case of PEL and what action should one take then?
    Jaap.

    Hai Japp,
    It depends on the volume of the data.
    The best way is drop index in pre mapping process and recreate it in post mapping process.
    You need to use EXECUTE IMMEDIATE command in the procedure to create or drop indexes.
    e.g:
    EXECUTE IMMEDIATE 'CREATE BITMAP INDEX INDX_BI_TABLE ON TABLE_NAME(COL_NAME)'
    Regards,
    Malli

  • ORA-00904 with bitmap indexes

    Hi,
    I'm running the following query:
    SELECT
    FLOW.PRODUCT_CODE,
    FLOW.CUSTOMER_SK,
    FLOW.BRAND_SK,
    26,
    FLOW.MPR_SK
    FROM     
    RSB_FACT_FLOW_SD          FLOW,
    RSB_DIM_FLOW               DIM
    WHERE     
    FLOW.FLOW_SK     = DIM.FLOW_SK
    AND     DIM.FLOW_ID                = 'CFRD'
    AND     FLOW.PRODUCT_CODE          = 'G'
    AND     FLOW.FLOW_DATE                >= '01 JAN 2006'
    AND     FLOW.FLOW_DATE                <= '31 JAN 2006'
    AND     EXISTS
         (     SELECT     1
              FROM     RSB_FACT_FLOW_SD          A,
                   RSB_DIM_FLOW          B
              WHERE     
              A.MPR_SK     = FLOW.MPR_SK
         AND A.RECEIVED_DATE >= FLOW.RECEIVED_DATE
              AND     B.FLOW_SK= A.FLOW_SK
              AND     B.FLOW_ID= 'WAO2'
              AND      A.REASON= '02CRO'
    I get ORA-00904: "FLOW"."RECEIVED_DATE": invalid identifier
    This is the defintion of the table:
    CREATE TABLE RSB_FACT_FLOW_SD
    PRODUCT_CODE CHAR(1) NOT NULL,
    WEEK_END_DATE DATE NOT NULL,
    CUSTOMER_SK NUMBER(10) NOT NULL,
    CUSTOMER_ATTRIBUTE_SK NUMBER(10) NOT NULL,
    MPR_SK NUMBER(10) NOT NULL,
    MPR_PROFILE_SK NUMBER(10) NOT NULL,
    SPECCOND_PROFILE_SK NUMBER(10) NOT NULL,
    BRAND_SK NUMBER(10) NOT NULL,
    FLOW_SK NUMBER(10) NOT NULL,
    FLOW_DATE DATE,
    RECEIVED_DATE DATE,
    VALIDATION_STATUS CHAR(1),
    FLOW_TYPE CHAR(1),
    RECEIVED_FROM_SENT_TO VARCHAR2(4),
    REASON VARCHAR2(255),
    FLOW_SEQUENCE NUMBER,
    CUSTOMER_SEGMENT_SK NUMBER(10),
    BRAND_PARTNER_SK NUMBER
    TABLESPACE DW_DATA
    PCTUSED 90
    PCTFREE 0
    PARALLEL
    LOGGING;
    CREATE BITMAP INDEX RSB_FACT_FLOW_SD_IX01 ON RSB_FACT_FLOW_SD
    (PRODUCT_CODE) TABLESPACE DW_INDEXES PARALLEL PCTFREE 0 NOLOGGING COMPUTE STATISTICS;
    CREATE BITMAP INDEX RSB_FACT_FLOW_SD_IX02 ON RSB_FACT_FLOW_SD
    (WEEK_END_DATE) TABLESPACE DW_INDEXES PARALLEL PCTFREE 0 NOLOGGING COMPUTE STATISTICS;
    CREATE BITMAP INDEX RSB_FACT_FLOW_SD_IX03 ON RSB_FACT_FLOW_SD
    (CUSTOMER_SK) TABLESPACE DW_INDEXES PARALLEL PCTFREE 0 NOLOGGING COMPUTE STATISTICS;
    CREATE BITMAP INDEX RSB_FACT_FLOW_SD_IX04 ON RSB_FACT_FLOW_SD
    (CUSTOMER_ATTRIBUTE_SK) TABLESPACE DW_INDEXES PARALLEL PCTFREE 0 NOLOGGING COMPUTE STATISTICS;
    CREATE BITMAP INDEX RSB_FACT_FLOW_SD_IX05 ON RSB_FACT_FLOW_SD
    (MPR_SK) TABLESPACE DW_INDEXES PARALLEL PCTFREE 0 NOLOGGING COMPUTE STATISTICS;
    CREATE BITMAP INDEX RSB_FACT_FLOW_SD_IX06 ON RSB_FACT_FLOW_SD
    (MPR_PROFILE_SK) TABLESPACE DW_INDEXES PARALLEL PCTFREE 0 NOLOGGING COMPUTE STATISTICS;
    CREATE BITMAP INDEX RSB_FACT_FLOW_SD_IX07 ON RSB_FACT_FLOW_SD
    (SPECCOND_PROFILE_SK) TABLESPACE DW_INDEXES PARALLEL PCTFREE 0 NOLOGGING COMPUTE STATISTICS;
    CREATE BITMAP INDEX RSB_FACT_FLOW_SD_IX08 ON RSB_FACT_FLOW_SD
    (BRAND_SK) TABLESPACE DW_INDEXES PARALLEL PCTFREE 0 NOLOGGING COMPUTE STATISTICS;
    CREATE BITMAP INDEX RSB_FACT_FLOW_SD_IX09 ON RSB_FACT_FLOW_SD
    (FLOW_SK) TABLESPACE DW_INDEXES PARALLEL PCTFREE 0 NOLOGGING COMPUTE STATISTICS;
    CREATE BITMAP INDEX RSB_FACT_FLOW_SD_IX10 ON RSB_FACT_FLOW_SD
    (RECEIVED_DATE) TABLESPACE DW_INDEXES PARALLEL PCTFREE 0 NOLOGGING COMPUTE STATISTICS;
    CREATE BITMAP INDEX RSB_FACT_FLOW_SD_IX11 ON RSB_FACT_FLOW_SD
    (FLOW_DATE) TABLESPACE DW_INDEXES PARALLEL PCTFREE 0 NOLOGGING COMPUTE STATISTICS;
    CREATE BITMAP INDEX RSB_FACT_FLOW_SD_IX12 ON RSB_FACT_FLOW_SD
    (CUSTOMER_SEGMENT_SK) TABLESPACE DW_INDEXES PARALLEL PCTFREE 0 NOLOGGING COMPUTE STATISTICS;
    CREATE BITMAP INDEX RSB_FACT_FLOW_SD_IX13 ON RSB_FACT_FLOW_SD
    (BRAND_PARTNER_SK) TABLESPACE DW_INDEXES PARALLEL PCTFREE 0 NOLOGGING COMPUTE STATISTICS;
    If I drop the indexes on the table then the error goes away.
    Any ideas??
    Sheena

    ( SELECT 1
    FROM RSB_FACT_FLOW_SD A,
    RSB_DIM_FLOW B
    WHERE
    A.MPR_SK = FLOW.MPR_SK
    AND A.RECEIVED_DATE >= FLOW.RECEIVED_DATE =====>>>>
    AND B.FLOW_SK= A.FLOW_SK
    AND B.FLOW_ID= 'WAO2'
    AND A.REASON= '02CRO'
    Your sub query has the problem.
    You didn't list flow table in the subquery, therefore, you subquery, dont understand about the column.
    specify flow table in the subquery.
    Your outquery tables doesn't recognized in the sub query.
    Jaffar

  • Simple SQL Query is not using Bitmap index

    Hello to All,
    We are having Oracle9i Database and using it for the datawarehouse purpose.
    I have created the bitmap index on calledinfo column and I am running the following simple query which takes serveral hours to complete:
    select * from ssp.ssp_2006_q4 where calledinfo='799992515f'
    OR
    select calledinfo from ssp.ssp_2006_q4 where calledinfo='799992515f'
    I don't know why it is not using the bitmap index: Can anybody help me here?
    Thanks in Advance
    Hashim

    I know why and everyone that has read Jonathan Lewis' book on the CBO knows why.
    Why? Because the CBO thinks the cost of using your index will be higher than the cost of ignoring it.
    To see what Oracle is thinking run an explain plan using DBMS_XPLAN for create the output and then rerun it with a hint forcing index usage.
    It is a mistake to believe that an index will always make things better. Issues of cardinality, clustering factor, etc. are very important.
    Post the explain plans if you have any questions about what they show:
    http://www.psoug.org/reference/explain_plan.html

  • Bitmap indexes and group by

    I'm trying to understand why Oracle 8.1.6 sometimes uses bitmap indexes sometimes not.
    Of course I have all the statistics, my bitmap indexes are valid and so on.
    The problem is this:
    - I have a customer table very very large
    - I have many columns with bitmap indexes
    - I run this statement:
    select education_key, count(*)
    from customer
    group by education_key
    and obtain a correct execution plan:
    0 SELECT STATEMENT Optimizer=CHOOSE (Cost=235 Card=5 Bytes=10)
    1 0 SORT (GROUP BY NOSORT) (Cost=235 Card=5 Bytes=10)
    2 1 BITMAP CONVERSION (COUNT)
    3 2 BITMAP INDEX (FULL SCAN) OF 'CL_EDU'
    with the use of the bitmap indexes (only five different values)
    - now I want to put a condition on a column
    which has a bitmap index.
    The new statement is:
    select education_key, count(*)
    from customer
    where age_key = 30
    group by education_key
    No join, only a scan of a sort of
    fact table. In this case Oracle
    doesn't use the bitmap index on
    education_key:
    0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3458 Card=5 Bytes=20
    1 0 SORT (GROUP BY) (Cost=3458 Card=5 Bytes=20)
    2 1 TABLE ACCESS (BY INDEX ROWID) OF 'CUSTOMER' (Cost=3395 C
    ard=18296 Bytes=73184)
    3 2 BITMAP CONVERSION (TO ROWIDS)
    4 3 BITMAP INDEX (SINGLE VALUE) OF 'CL_AGE'
    With this execution plan Oracle has to
    read some blocks from the table when I
    think that using both the bitmap indexes
    the query is faster.
    Someone knows why Oracle has this
    behaviour? I'm trying to change
    many things (also altering statistics
    value), but it seems that with a
    condition Oracle doesn'use the bitmap
    index on the group by column.
    null

    Hi Michael, what is the address for the lasagne? ....
    In init.ora.parms I had 32Mb for bitmap index merge, I suppose it's enough, hovewer I have tried to increase it and nothing changes.
    I already use STAR_TRASFORMATION_ENABLED=TRUE.
    I have tried with different level of statistics (estimate, compute, also with very precise histograms), always the same
    behaviour. I have also tried to change, in a manual way, the statistics in order to change the Oracle behaviour but nothing ...
    For this particular statement even if I use the INDEX_COMBINE hint, I mantain the same execution plan.
    I use CHOOSE, FIRST_ROWS, ALL_ROWS: always the same behaviour.
    I think that Oracle is not able to use a bitmap index on a column involved in a group by when there is another condition in the select.
    Hovewer with bitmap indexes, I have many other problems (to read 1% of the table Oracle decides to make a full table scan even if there are the correct bitmap indexes ...).
    Many of them are solved using BITMAP_INDEX, but it's difficult to use it in a query tool like Discover or Business Objects because I have to fix the use of INDEX_COMBINE also in situation in which this use is not correct from a performance point of view.
    The life with the query optimizer is very hard!
    Thank you for your guesses

  • Bitmap index column goes for full table scan

    Hi all,
    Database : 10g R2
    OS : Windows xp
    my select query is :
    SELECT tran_id, city_id, valid_records
    FROM transaction_details
    WHERE type_id=101;
    And the Explain Plan is :
    Plan
    SELECT STATEMENT ALL_ROWSCost: 29 Bytes: 8,876 Cardinality: 634
    1 TABLE ACCESS FULL TABLE TRANSACTION_DETAILS** Cost: 29 Bytes: 8,876 Cardinality: 634
    total number of rows in the table = 1800 ;
    distinct value of type_ids are 101,102,103
    so i created a bit map index on it.
    CREATE BITMAP INDEX btmp_typeid ON transaction_details
    (type_id)
    LOGGING
    NOPARALLEL;
    after creating the index, the explain plan shows the same. why it goes for full table scan?.
    Kindly share ur idea on this.
    Edited by: 887268 on Apr 3, 2013 11:01 PM
    Edited by: 887268 on Apr 3, 2013 11:02 PM

    >
    I am sorry for being ignorant, can you please cite any scenario of locking due to bitmap indices? A link can be useful as well.
    >
    See my full reply in this thread
    Bitmap index for FKs on Fact tables
    >
    ETL is affected because DML operations (INSERT/UPDATE/DELETE) on tables with bitmapped indexes can have serious performance issues due to the serialization involved. Updating a single bit-mapped column value (e.g. from 'M' to 'F' for gender) requires both bitmapped index blocks to be locked until the update is complete. A bitmap index stored ROWID ranges (min rowid - max rowid) than can span many, many records. The entire 'range' of rowids is locked in order to change just one value.
    To change from 'M' the 'M' rowid range for that one row is locked and the ROWID must be removed from the range byt clearing the bit. To change to 'F' the 'F' rowid id range needs to be found, locked and the bit set that corresponds to that rowid. No other rows with rowids in the range can be changed since this is a serial operation. If the range includes 1000 rows and they all need changed it takes 1000 serial operations.

  • Why bitmap index not working?

    I have a table containing 4.2M rows and 16 distinct fs_type_code. So I created a bitmap index ntr_fs_type_code_ind on the column. Then I run the query:
    update /*+ INDEX_COMBINE(NTR_FS_TYPE_CODE_IND) */ ntr_CORPALL_20050801 d
    set eqt_basket_id = NULL, index_weight = NULL
    where
    fs_type_code in ('EQGR','EQVG','EQDL')
    and eqt_basket_id = equity_symbol
    and index_weight = 0;
    I clearly tell optimizer to use the bitmap index. But it turns out the optimizer ignore the index and still use full table scan.
    When I created regular b-tree index, the same query (without hint) use index scan.
    Can anybody tell me why the bitmap index not working here?
    Thanks,

    <quote>I clearly tell optimizer to use the bitmap index</quote>
    You are clearly not doing it right (see bellow). But anyway …
    1. For frequently modified tables (OLTP type application) you may want to rethink the applicability of bitmap indexes …
    low cardinality in itself is not enough justification for using bitmap indexes.
    2. Your update statement may modify a minority, a majority, or anything in between of the total number of
    rows in your table … here is no one universal access method which is always better
    (if there were one they wouldn’t have bothered with coding the rest).
    In short, index access is not always the better way.
    3. Don’t rush into hinting (because that optimizer is such a lousy piece of software) …
    and if you do, make sure you do it correctly and for the right reasons.
    flip@FLOP> create table t as select * from all_objects;
    Table created.
    flip@FLOP> insert into t select * from t;
    30043 rows created.
    flip@FLOP> insert into t select * from t;
    60086 rows created.
    flip@FLOP> insert into t select * from t;
    120172 rows created.
    flip@FLOP> insert into t select * from t;
    240344 rows created.
    flip@FLOP> create bitmap index tx on t (object_type);
    Index created.
    flip@FLOP> exec dbms_stats.gather_table_stats(user,'T',method_opt=>'for all indexed columns',cascade=>true)
    PL/SQL procedure successfully completed.
    flip@FLOP> select object_type,count(*) from t group by rollup(object_type);
    OBJECT_TYPE          COUNT(*)
    CONSUMER GROUP             32
    DIRECTORY                  32
    EVALUATION CONTEXT         16
    FUNCTION                 1648
    INDEX                   23152
    INDEX PARTITION          2048
    INDEXTYPE                 128
    JAVA CLASS             163024
    JAVA RESOURCE            3120
    LIBRARY                   224
    LOB                        16
    MATERIALIZED VIEW          32
    OPERATOR                  464
    PACKAGE                  5488
    PACKAGE BODY               32
    PROCEDURE                 640
    SEQUENCE                  144
    SYNONYM                202512
    TABLE                   18816
    TABLE PARTITION           880
    TRIGGER                  4768
    TYPE                    10640
    TYPE BODY                  16
    VIEW                    42816
                           480688
    flip@FLOP> set autotrace on explain
    update few rows … CBO goes with the index … no hinting
    flip@FLOP> update t d set object_id=object_id-1 where object_type in ('INDEX','PACKAGE','PACKAGE BODY','TABLE');
    47488 rows updated.
    Elapsed: 00:00:09.02
    Execution Plan
       0      UPDATE STATEMENT Optimizer=CHOOSE (Cost=536 Card=47488 Bytes
              =1044736)
       1    0   UPDATE OF 'T'
       2    1     INLIST ITERATOR
       3    2       BITMAP CONVERSION (TO ROWIDS)
       4    3         BITMAP INDEX (SINGLE VALUE) OF 'TX'
    update lots of rows … CBO goes with the ft … no hinting
    flip@FLOP> update t d set object_id=object_id-1 where object_type in ('JAVA CLASS','SYNONYM');
    365536 rows updated.
    Elapsed: 00:00:25.04
    Execution Plan
       0      UPDATE STATEMENT Optimizer=CHOOSE (Cost=638 Card=365536 Byte
              s=8041792)
       1    0   UPDATE OF 'T'
       2    1     TABLE ACCESS (FULL) OF 'T' (Cost=638 Card=365536 Bytes=8
              041792)
    update lots of rows … wrong hint syntax … CBO goes with the ft
    flip@FLOP> update /*+ index_combine(tx) */ t d set object_id=object_id-1 where object_type in ('JAVA CLASS','SYNONYM');
    365536 rows updated.
    Elapsed: 00:00:21.00
    Execution Plan
       0      UPDATE STATEMENT Optimizer=CHOOSE (Cost=638 Card=365536 Byte
              s=8041792)
       1    0   UPDATE OF 'T'
       2    1     TABLE ACCESS (FULL) OF 'T' (Cost=638 Card=365536 Bytes=8
              041792)
    update lots of rows … correct hint syntax … CBO goes with the index … but was it better than the ft?
    flip@FLOP> update /*+ index_combine(d tx) */ t d set object_id=object_id-1 where object_type in ('JAVA CLASS','SYNONYM')
    365536 rows updated.
    Elapsed: 00:00:25.01
    Execution Plan
       0      UPDATE STATEMENT Optimizer=CHOOSE (Cost=1665 Card=365536 Byt
              es=8041792)
       1    0   UPDATE OF 'T'
       2    1     INLIST ITERATOR
       3    2       BITMAP CONVERSION (TO ROWIDS)
       4    3         BITMAP INDEX (SINGLE VALUE) OF 'TX'
    flip@FLOP>

  • Using Bitmap Index over db link.

    I've a problem with the following query:
    select count(*)
    from TABLE_A@db_link TABLE_A, TABLE_B
    where TABLE_A.ACCEPTTIME = TABLE_B.TIME_B
    The above query is doing a full table scan (even after forcing index hints) on TABLE_A which has about 300M records.
    TABLE_A is a local table while TABLE_B is remotely accesed using db_link.
    There is a bitmap index created on the ACCEPT_TIME field of TABLE_A which is not used by the query. However when I fire this query:
    Am I missing something here? How can I make the optimizer use the bitmap index on TABLE_A using remote db_link?
    Here is the explain plan for the above query:
    Operation     Object Name     Rows     Bytes     Cost     Object Node     In/Out     PStart     PStop
    SELECT STATEMENT
    Optimizer Mode=ALL_ROWS          1           2                     
    SORT AGGREGATE          1      17                          
    NESTED LOOPS          1      17      2                     
    REMOTE     .COPY_STM     1      9      2
         STAG_PLMSPDB1.SMART.COM.PH     SERIAL          
    INDEX RANGE SCAN     SYSTEM.DIM_TIME_INDX1     1      8      0                     
    Regards,
    Raj

    Here is a simple case to explain the problem more clearly:
    1. dept: database1 (small table dimension with 4 rows)
    2. emp: database2 (large table fact with 50K rows)
    3. Table emp has bitmap index on column "deptno"
    4. Both tables are analyzed with defualt values using DBMS_STATS.GATHER_TABLE AND INDEX STATS
    5. DB Link db2 is created from database1 to database2
    Observations:
    a) On Database2 when the following query is issued:
    select count(*) from emp@DATABASE1 emp, dept where emp.deptno = dept.deptno
    It does not use the bitmap index.
    b) On Database1 when the following query is issued:
    select count(*) from emp emp, dept@DATABASE2 where emp.deptno = dept.deptno
    It does use the bitmap index since it is available optimizer has this information locally.
    My question is how can I make use of the statistics effectively, so that the optimizer knows it has to use the bitmap index present in the remote db.
    Regards,
    Raj

  • Trying to make use of bitmap indexes

    Hello!
    I have a table that contains about 16 mill rows and each night about
    60.000-70.000 rows are proccessed against the table so that part of the rows
    is updated and another part is inserted.
    The table contains three IDEAL columns for bitmap indexes the first of which
    may have only two, the second three and the third four distinct values.
    I was planning to change the index type on these columns to BITMAP but
    Oracle doesnt recommend to build BITMAP indexes on heavily updated or inserted
    columns.
    So the only use of bitmap indexes turns out to be read-only tables.
    From the other hand a sloution might be dropping indexes before the load and rebuilding them after the load has completed what can lead to often tablespace fragmentations.
    So, the question is how can I use bitmap indexes in a case like this one?
    What are wayouts?
    Thank you very mcuh for the reply.

    >
    The table contains three IDEAL columns for bitmap indexes the first of which
    may have only two, the second three and the third four distinct values.
    Contrary to popular legend, and possibly contrary even to the manuals and Metalink, these columns are NOT necessarily ideal for bitmap indexes. Consider a query with:
        col1 = '1_of_2'
    and col2 = '1_of_3'
    and col3 = '1_of_4'You have a total of 24 possible combinations. Given your 16M rows, this means that on average the optimizer will expect to collect about 670.000 rows spread across something like 100,000 to 130,000 blocks. Under these circumstances you may find that Oracle doesn't use the indexes anyway (unless you fool it by fiddling with parameters like the optimizer_index_cost_adj, and that's generally a bad idea) - and if the model is a reasonable description of the actual data it probably shouldn't use the indexes.
    There are various special circumstance that might make the indexes effective for querying, though. (Note - at this point I'm not considering the impact on inserts, updates and deletes). The most obvious example is where all three columns each have at least one very repetitive value and all your queries are trying to find data for the remaining "rare" values. If this is the case then you need to index the columns and collect histograms on the columns so that the optimiser can model the data correctly; and then you may also need to modify your SQL to ensure that your queries against these columns always use literal values, not bind variables.
    If some of your queries are supposed to return small amounts of data, there are various mechanisms you could use to do this efficiently. If your queries are always going to return large amounts of data, then there are other strategies that are likely to be more appropriate.
    Regards
    Jonathan Lewis
    http://jonathanlewis.wordpress.com
    http://www.jlcomp.demon.co.uk

  • Multi-column BITMAP index vs. multiple BITMAP indices?

    Given the table (simple, made-up example):
    CREATE TABLE applicant_diversity_info (
    applicant_diversity_id NUMBER(12), PRIMARY KEY(applicant_diversity_id),
    apply_date DATE,
    ssn_salted_md5 RAW(16),
    gender CHAR(1), CHECK ( (gender IS NULL OR gender IN ('M','F')) ),
    racial_continent VARCHAR2(30), CHECK ( (racial_continent IS NULL
    OR racial_continent IN ('Europe','Africa','America','Asia_Pacific')) ),
    ethnic_supergroup VARCHAR2(30), CHECK ( (ethnic_supergroup IS NULL OR ethnic_supergroup IN ('Latin American','Other')) ),
    hire_salary NUMBER(11,2),
    hire_month DATE,
    termination_salary NUMBER(11,2),
    termination_month DATE,
    termination_cause VARCHAR2(30), CHECK ( (termination_cause IS NULL
    OR termination_cause IN ('Resigned','Leave of Absence','Laid Off','Performance','Cause')) )
    Oracle (syntactically) allows me to create either one BITMAP index over all four small-cardinality columns
    CREATE BITMAP INDEX applicant_diversity_diversity_idx ON applicant_diversity_info (
    gender, racial_continent, ethnic_supergroup, termination_reason );
    or four independent indexes
    CREATE BITMAP INDEX applicant_diversity_gender_idx ON applicant_diversity_info ( gender );
    CREATE BITMAP INDEX applicant_diversity_race_idx ON applicant_diversity_info ( raceial_continent );
    etc.
    What is the difference between the two approaches; is there any meaningful difference in disk-space between the one multi-colum index and the four single-column indexes? Does it make a difference in what the query-planner will consider?
    And, if I define one multi-column BITMAP index, does the order of columns matter?

    >
    What is the difference between the two approaches; is there any meaningful difference in disk-space between the one multi-colum index and the four single-column indexes? Does it make a difference in what the query-planner will consider?
    And, if I define one multi-column BITMAP index, does the order of columns matter?
    >
    You may want to read this two-part blog, that answers that exact question, by recognized expert Richard Foote
    http://richardfoote.wordpress.com/2010/05/06/concatenated-bitmap-indexes-part-i-two-of-us/
    http://richardfoote.wordpress.com/2010/05/12/concatenated-bitmap-indexes-part-ii-everybodys-got-to-learn-sometime/
    As with many things Oracle the answer is 'it depends'.
    In short the same considerations apply for a concatenated index whether it is bitmap or b-tree: 1) will the leading column usually be in the predicate and 2) will most or all of the index columns be specified in the queries.
    Here are some quotes from part 1
    >
    Many of the same issues and factors in deciding to create a single, multi-column index vs. several, single column indexes apply to Bitmap indexes as they do with B-Tree indexes, although there are a number of key differences to consider as well.
    Another thing to note regarding a concatenated Bitmap index is that the potential number of index entries is a product of distinct combinations of data of the indexed columns.
    A concatenated Bitmap index can potentially use less or more space than corresponding single column indexes, it depends on the number of index entries that are derived and the distribution of the data with the table.
    >
    Here is the lead quote from part 2
    >
    The issues regarding whether to go for single column indexes vs. concatenated indexes are similar for Bitmap indexes as they are for B-Tree indexes.
    It’s generally more efficient to access a concatenated index as it’s only the one index with less processing and less throwaway rowids/rows to contend with. However it’s more flexible to have single column indexes, especially for Bitmap indexes that are kinda designed to be used concurrently, as concatenated indexes are heavily dependant on the leading column being known in queries.

  • Bitmap index Vs B-Tree index

    Hi All,
    Could some one please let me know how Bitmap indexes are useful compared to B-Tree indexes on low-cardinality columns ?.
    Thanks,
    -Kumar.

    >>
    As Re: why oracle db 9i optimizer can't choose to use the bitmap index? there are a number of issues with bitmap indexes. Your best bet is to read these three articles by Jonathan Lewis.
    It does pay us to understand how the optimizer works with bitmap indexes. I posted some Re: Cost-based optimizer behavior to show how indexes on even very low valued columns can be useful in certain circumstances.
    Cheers, APC
    Blog : http://radiofreetooting.blogspot.com/

Maybe you are looking for