Peformance tuning of query using bitmap indexes

Hello guys
I just have a quick question about tuning the performance of sql query using bitmap indexes..
Currently, there are 2 tables, date and fact. Fact table has about 1 billion row and date dim has about 1 million. These 2 tables are joined by 2 columns:
Date.Dateid = Fact.snapshot.dates and Date.companyid = fact.companynumber
I have query that needs to be run as the following:
Select dates.dayofweek, dates,dates, fact.opened_amount from dates, facts
where Date.Dateid = Fact.snapshot.dates and Date.companyid = fact.companynumber and dates.dayofweek = 'monday'.
Currently this query is running forever. I think it is joining that takes a lot of time. I have created bitmap index on dayofweek column because it's low on distinctive rows. But it didn't seem to speed up with the performance..
I'd like to know what other indexes will be helpful for me.. I am thinking of creating another one for companynumber since it also have low distinctive records.
Currently the query is being generated by frontend tools like OBIEE so I can't change the sql nor can't I purge data or create smaller table, I have to what with what I have..
So please let me know your thoughts in terms of performance tunings.
Thanks

The explain plan is:
Row cost Bytes
Select statement optimizer 1 1
nested loops 1 1 299
partition list all 1 0 266
index full scan RD_T.PK_FACTS_SNPSH 1 0 266
TABLE ACCESS BY INDEX ROWID DATES_DIM 1 1 33
INDEX UNIQUE SCAN DATES_DIM_DATE 1 1
There is no changes nor wait states, but query is taking 18 mins to return results. When it does, it returns 1 billion rows, which is the same number of rows of the fact table....(strange?)That's not a bitmap plan. Plans using bitmaps should have steps indicating bitmap conversions; this plan is listing ordinary btree index access. The rows and bytes on the plan for the volume of data you suggested have to be incorrect. (1 row instead of 1B?????)
What version of the data base are you using?
What is your partition key?
Are the partioned table indexes global or local? Is the partition key part of the join columns, and is it indexed?
Analyze the tables and all indexes (use dbms_stats) and see if the statistics get better. If that doesn't work try the dynamic sampling hint (there is some overhead for this) to get statistics at runtime.
I have seen stats like the ones you listed appear in 10g myself.
Edited by: riedelme on Oct 30, 2009 10:37 AM

Similar Messages

  • Tuning OBIEE query with DB index, but it's getting slower

    Hello guys
    I just have a quick question about tuning the performance of sql query using bitmap indexes..
    Currently, there are 2 tables, date and fact. Fact table has about 1 billion row and date dim has about 1 million. These 2 tables are joined by 2 columns:
    Date.Dateid = Fact.snapshot.dates and Date.companyid = fact.companynumber
    I have query that needs to be run as the following:
    Select dates.dayofweek, dates,dates, fact.opened_amount from dates, facts
    where Date.Dateid = Fact.snapshot.dates and Date.companyid = fact.companynumber and dates.dayofweek = 'monday'.
    Currently this query is running forever. I think it is joining that takes a lot of time. I have created bitmap index on dayofweek column because it's low on distinctive rows. But it didn't seem to speed up with the performance, but rather made it worse. The explain plan before and after creating that index was the same as:
    Select statement optimizer
    nested loops
    partition list all
    index full scan RD_T.PK_FACTS_SNPSH
    TABLE ACCESS BY INDEX ROWID DATES_DIM
    INDEX UNIQUE SCAN DATES_DIM_DATE
    It seems the bitmap index I created for DATES_DIM wasn't used... Also, I am thinking what other indexes I should create for fact table..
    I'd like to know what other indexes will be helpful for me and on which table & columns?.. I am thinking of creating another one for companynumber since it also have low distinctive records.
    Currently I can't purge data or create smaller table, I have to what with what I have..
    So please let me know your thoughts in terms of performance tunings for such situation..
    Thanks

    Jack,
    Thank you for your response. It helped me to clean up the query. All the changes did not give a much better explain plan - at least not to my inexperienced eyes - but the total execution time for the query is now reduced to under two minutes. The query as it is now:
    select /*+ ordered all_rows */ x.rowid1
    from table(sdo_join('CYCLORAMA','GEOMETRIE','CYCLORAMA','GEOMETRIE','distance=3 mask=ANYINTERACT')) x
    , cyclorama s, cyclorama t
    where not x.rowid1 = x.rowid2
    and s.rowid = x.rowid1 and x.rowid2 = t.rowid
    and s.datasetid != t.datasetid
    and s.opnamedatum < t.opnamedatum;Because the docs state that mask=FILTER is the default, I added an explicit mask=ANYINTERACT to the sdo_join parameters when I removed the sdo_distance from the query. Still, the query returns 205035 records with the sdo_distance, and 205125 without. But this may be the result of the extra 0.001 from sdo_dim. I did not investigate as the 3 meter is not crucial.
    I believe I already had a mechanism in place to reduce the number of self-joins with "not x.rowid1 = x.rowid2" and "s.opnamedatum < t.opnamedatum". I can not guarantee that for all records s.opnamedatum < t.opnamedatum equals x.rowid1 < x.rowid2.
    Based on the [url http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14255/sdo_operat.htm#BGEDJIBF]docs, I finally added an 'ordered' hint and reshuffled the tables in the from clause.
    I'm happy with performance now, and creating a new table with the records to keep should not be a problem. Still I'm curious about the following:
    <li>Is it worth optimizing the SDO_DIM_ARRAY for the original table, e.g. narrowing the range of coordinate values?
    <li>How can sdo_join best be used for an anti-join, to select the records to keep?
    Thank you,
    J-----.

  • Can downloaded oracle9i Enterprise Edition use Bitmap index?

    Hello there,
    I have a downloaded Oracle9i Enterprise Edition. After I create some bitmap index on a partitioned table, I use the following sql statement to check the bitmap index:
    select index_name, index_type, status from user_index;
    It tells me that all the statuses of the bitmap indexes are "N/A" (Not availabe). Does that mean I can NOT use bitmap index in this downloaded Enterprise version?
    If I must use bitmap indexes, what should I do?
    Many thanks in advance!
    -wendy

    are you creating a local index on the partitioned table?

  • How to use bitmap index

    when we will use bitmap index in oracle?

    hi,
    you can take a look this documents
    http://dylanwan.wordpress.com/2008/02/01/bitmap-index-when-to-use-it/
    http://www.oracle.com/technetwork/articles/sharma-indexes-093638.html
    regards,

  • 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

  • Why does not my query use an index?

    I have a table with some processed rows (state: 9) and some unprocessed rows (states: 0,1,2,3,4).
    This table has over 120000 rows, but this number will grow.
    Most of the rows are processed and most of them also contain a group id. Number of groups is relatively small (let's assume 20).
    I would like to obtain the oldest some_date for every group. This values has to be outer joined to a on-line report (contains one row for each group).
    Here is my set-up:
    Tested on: 10.2.0.4 (Solaris), 10.2.0.1 (WinXp)
    drop table t purge;
    create table t(
      id number not null primary key,
      grp_id number,
      state number,
      some_date date,
      pad char(200)
    insert into t(id, grp_id, state, some_date, pad)
    select level,
         trunc(dbms_random.value(0,20)),
            9,
            sysdate+dbms_random.value(1,100),
            'x'
    from dual
    connect by level <= 120000;
    insert into t(id, grp_id, state, some_date, pad)
    select level + 120000,
         trunc(dbms_random.value(0,20)),
            trunc(dbms_random.value(0,5)),
            sysdate+dbms_random.value(1,100),
            'x'
    from dual
    connect by level <= 2000;
    commit;
    exec dbms_stats.gather_table_stats(user, 'T', estimate_percent=>100, method_opt=>'FOR ALL COLUMNS SIZE 1');
    Tom Kyte's printtab
    ==============================
    TABLE_NAME                    : T
    NUM_ROWS                      : 122000
    BLOCKS                        : 3834I know, this could be easily solved by fast refresh on commit materialized view like this:
    select
      grp_id,
      min(some_date),
    from
      t
    where
      state in (0,1,2,3,4)
    grpup by
      grp_id;+ I have to create log on (grp_id, some_date, state)
    Number of rows with active state will be always relatively small. Let's assume 1000-2000.
    So my another idea was to create a selective index. An index which would contain only data for rows with an active state.
    Something like this:
    create index fidx_active on t ( 
      case state 
        when 0 then grp_id
        when 1 then grp_id
        when 2 then grp_id
        when 3 then grp_id
        when 4 then grp_id
      end,
      case state
        when 0 then some_date
        when 1 then some_date
        when 2 then some_date
        when 3 then some_date
        when 4 then some_date
      end) compress 1; so a tuple (group_id, some_date) is projected to tuple (null, null) when the state is not an active state and therefore it is not indexed.
    We can save even more space by compressing 1st expression.
    analyze index idx_grp_state_date validate structure;
    select * from index_stats
    @pr
    Tom Kyte's printtab
    ==============================
    HEIGHT                        : 2
    BLOCKS                        : 16
    NAME                          : FIDX_ACTIV
    LF_ROWS                       : 2000 <-- we're indexing only active rows
    LF_BLKS                       : 6 <-- small index: 1 root block with 6 leaf blocks
    BR_ROWS                       : 5
    BR_BLKS                       : 1
    DISTINCT_KEYS                 : 2000
    PCT_USED                      : 69
    PRE_ROWS                      : 25
    PRE_ROWS_LEN                  : 224
    OPT_CMPR_COUNT                : 1
    OPT_CMPR_PCTSAVE              : 0Note: @pr is a Tom Kyte's print table script adopted by Tanel Poder (I'm using Tanel's library) .
    Then I created a query to be outer joined to the report (report contains a row for every group).
    I want to achieve a full scan of the index.
    select
      case state -- 1st expression
        when 0 then grp_id
        when 1 then grp_id
        when 2 then grp_id
        when 3 then grp_id
        when 4 then grp_id
      end grp_id,
      min(case state --second expression
            when 0 then some_date
            when 1 then some_date
            when 2 then some_date
            when 3 then some_date
            when 4 then some_date
          end) as mintime
    from t 
    where
      case state --1st expression: at least one index column has to be not null
        when 0 then grp_id
        when 1 then grp_id
        when 2 then grp_id
        when 3 then grp_id
        when 4 then grp_id
      end is not null
    group by
      case state --1st expression
        when 0 then grp_id
        when 1 then grp_id
        when 2 then grp_id
        when 3 then grp_id
        when 4 then grp_id
      end;-------------
    Doc's snippet:
    13.5.3.6 Full Scans
    A full scan is available if a predicate references one of the columns in the index. The predicate does not need to be an index driver. A full scan is also available when there is no predicate, if both the following conditions are met:
    All of the columns in the table referenced in the query are included in the index.
    At least one of the index columns is not null.
    A full scan can be used to eliminate a sort operation, because the data is ordered by the index key. It reads the blocks singly.
    13.5.3.7 Fast Full Index Scans
    Fast full index scans are an alternative to a full table scan when the index contains all the columns that are needed for the query, and at least one column in the index key has the NOT NULL constraint. A fast full scan accesses the data in the index itself, without accessing the table. It cannot be used to eliminate a sort operation, because the data is not ordered by the index key. It reads the entire index using multiblock reads, unlike a full index scan, and can be parallelized.
    You can specify fast full index scans with the initialization parameter OPTIMIZER_FEATURES_ENABLE or the INDEX_FFS hint. Fast full index scans cannot be performed against bitmap indexes.
    A fast full scan is faster than a normal full index scan in that it can use multiblock I/O and can be parallelized just like a table scan.
    So the question is: Why does oracle do a full table scan?
    Everything needed is in the index and one expression is not null, but index (fast) full scan is not even considered by CBO (I did a 10053 trace)
    | Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    |   1 |  HASH GROUP BY     |      |      1 |     85 |     20 |00:00:00.11 |    3841 |
    |*  2 |   TABLE ACCESS FULL| T    |      1 |   6100 |   2000 |00:00:00.10 |    3841 |
    Predicate Information (identified by operation id):
       2 - filter(CASE "STATE" WHEN 0 THEN "GRP_ID" WHEN 1 THEN "GRP_ID" WHEN 2
                  THEN "GRP_ID" WHEN 3 THEN "GRP_ID" WHEN 4 THEN "GRP_ID" END  IS NOT NULL)Let's try some minimalistic examples. Firstly with no FBI.
    create index idx_grp_id on t(grp_id);
    select grp_id,
           min(grp_id) min
    from t
    where grp_id is not null
    group by grp_id;
    | Id  | Operation             | Name       | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
    |   1 |  HASH GROUP BY        |            |      1 |     20 |     20 |00:00:01.00 |     244 |    237 |
    |*  2 |   INDEX FAST FULL SCAN| IDX_GRP_ID |      1 |    122K|    122K|00:00:00.54 |     244 |    237 |
    Predicate Information (identified by operation id):
       2 - filter("GRP_ID" IS NOT NULL)This kind of output I was expected to see with FBI. Index FFS was used although grp_id has no NOT NULL constraint.
    Let's try a simple FBI.
    create index fidx_grp_id on t(trunc(grp_id));
    select trunc(grp_id),
           min(trunc(grp_id)) min
    from t
    where trunc(grp_id) is not null
    group by trunc(grp_id);
    | Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    |   1 |  HASH GROUP BY     |      |      1 |     20 |     20 |00:00:00.94 |    3841 |
    |*  2 |   TABLE ACCESS FULL| T    |      1 |   6100 |    122K|00:00:00.49 |    3841 |
    Predicate Information (identified by operation id):
       2 - filter(TRUNC("GRP_ID") IS NOT NULL)Again, index (fast) full scan not even considered by CBO.
    I tried:
    alter table t modify grp_id not null;
    alter table t add constraint trunc_not_null check (trunc(grp_id) is not null);I even tried to set table hidden column (SYS_NC00008$) to NOT NULL
    It has no effect, FTS is still used..
    Let's try another query:
    select distinct trunc(grp_id)
    from t
    where trunc(grp_id) is not null
    | Id  | Operation             | Name        | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    |   1 |  HASH UNIQUE          |             |      1 |     20 |     20 |00:00:00.85 |     244 |
    |*  2 |   INDEX FAST FULL SCAN| FIDX_GRP_ID |      1 |    122K|    122K|00:00:00.49 |     244 |
    Predicate Information (identified by operation id):
       2 - filter("T"."SYS_NC00008$" IS NOT NULL)Here the index FFS is used..
    Let's try one more query, very similar to the above query:
    select trunc(grp_id)
    from t
    where trunc(grp_id) is not null
    group by trunc(grp_id)
    | Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    |   1 |  HASH GROUP BY     |      |      1 |     20 |     20 |00:00:00.86 |    3841 |
    |*  2 |   TABLE ACCESS FULL| T    |      1 |    122K|    122K|00:00:00.49 |    3841 |
    Predicate Information (identified by operation id):
       2 - filter(TRUNC("GRP_ID") IS NOT NULL)And again no index full scan..
    So my next question is:
    What are the restrictions which prevent index (fast) fullscan to be used in these scenarios?
    Thank you very much for your answers.
    Edited by: user1175494 on 16.11.2010 15:23
    Edited by: user1175494 on 16.11.2010 15:25

    I'll start off with the caveat that i'm no Johnathan Lewis so hopefully someone will be able to come along and give you a more coherent explanation than i'm going to attempt here.
    It looks like the application of the MIN function against the case statement is confusing the optimizer and disallowing the usage of your FBI. I tested this against my 11.2.0.1 instance and your query chooses the fast full scan without being nudged in the right direction.
    That being said, i was able to get this to use a fast full scan on my 10 instance, but i had to jiggle the wires a bit. I modified your original query slightly, just to make it easier to do my fiddling.
    original (in the sense that it still takes the full table scan) query
    with data as
      select
        case state -- 1st expression
          when 0 then grp_id
          when 1 then grp_id
          when 2 then grp_id
          when 3 then grp_id
          when 4 then grp_id
        end as grp_id,
        case state --second expression
              when 0 then some_date
              when 1 then some_date
              when 2 then some_date
              when 3 then some_date
              when 4 then some_date
        end as mintime
      from t
      where
        case state --1st expression: at least one index column has to be not null
          when 0 then grp_id
          when 1 then grp_id
          when 2 then grp_id
          when 3 then grp_id
          when 4 then grp_id
        end is not null
      and
        case state --second expression
              when 0 then some_date
              when 1 then some_date
              when 2 then some_date
              when 3 then some_date
              when 4 then some_date
        end is not null 
    select--+ GATHER_PLAN_STATISTICS
      grp_id,
      min(mintime)
    from data
    group by grp_id;
    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'allstats  +peeked_binds'));
    | Id  | Operation        | Name | Starts | E-Rows | A-Rows |      A-Time   | Buffers |
    |   1 |  HASH GROUP BY        |       |      2 |      33 |       40 |00:00:00.07 |    7646 |
    |*  2 |   TABLE ACCESS FULL| T       |      2 |      33 |     4000 |00:00:00.08 |    7646 |
    Predicate Information (identified by operation id):
       2 - filter((CASE "STATE" WHEN 0 THEN "GRP_ID" WHEN 1 THEN "GRP_ID" WHEN 2
               THEN "GRP_ID" WHEN 3 THEN "GRP_ID" WHEN 4 THEN "GRP_ID" END  IS NOT NULL AND
               CASE "STATE" WHEN 0 THEN "SOME_DATE" WHEN 1 THEN "SOME_DATE" WHEN 2 THEN
               "SOME_DATE" WHEN 3 THEN "SOME_DATE" WHEN 4 THEN "SOME_DATE" END  IS NOT
               NULL))
    modified version where we prevent the MIN function from being applied too early, by using ROWNUM
    with data as
      select
        case state -- 1st expression
          when 0 then grp_id
          when 1 then grp_id
          when 2 then grp_id
          when 3 then grp_id
          when 4 then grp_id
        end as grp_id,
        case state --second expression
              when 0 then some_date
              when 1 then some_date
              when 2 then some_date
              when 3 then some_date
              when 4 then some_date
        end as mintime
      from t
      where
        case state --1st expression: at least one index column has to be not null
          when 0 then grp_id
          when 1 then grp_id
          when 2 then grp_id
          when 3 then grp_id
          when 4 then grp_id
        end is not null
      and
        case state --second expression
              when 0 then some_date
              when 1 then some_date
              when 2 then some_date
              when 3 then some_date
              when 4 then some_date
        end is not null 
      and rownum > 0
    select--+ GATHER_PLAN_STATISTICS
      grp_id,
      min(mintime)
    from data
    group by grp_id;
    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'allstats  +peeked_binds'));
    | Id  | Operation           | Name        | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    |   1 |  HASH GROUP BY           |            |      2 |     20 |     40 |00:00:00.01 |      18 |
    |   2 |   VIEW                |            |      2 |     33 |   4000 |00:00:00.07 |      18 |
    |   3 |    COUNT           |            |      2 |      |   4000 |00:00:00.05 |      18 |
    |*  4 |     FILTER           |            |      2 |      |   4000 |00:00:00.03 |      18 |
    |*  5 |      INDEX FAST FULL SCAN| FIDX_ACTIVE |      2 |     33 |   4000 |00:00:00.01 |      18 |
    Predicate Information (identified by operation id):
       4 - filter(ROWNUM>0)
       5 - filter(("T"."SYS_NC00006$" IS NOT NULL AND "T"."SYS_NC00007$" IS NOT NULL))

  • How to find out if your query uses the indexes?

    How can one tell if the query being issued is using your indexes or doing full table scans?
    Thank you.

    Thank you.
    Ok, let me see if I understand it. So, having an
    index may not speed things up.True
    Full table scans are not bad at all -- as I have it
    in my head. The query I ran before was: select *
    from table1;In that case an index would only slow things down; you are asking it to get all the information from the table - it has to read all of the table ( a full scan).
    >
    So full table scans and index have to do with the db
    block size and the size of the row correct?
    Block size and row size don't have a huge amount to do with it, but they do play a role.
    Let me ask: How does one know the size of a row and
    then the best option for the db blocks? Block size is a global setting (at the tablespace level I think). You would not likely change the block size based on the average row length in any one table. It would be about the last thing you might look at in terms of tuning (though you might consider it up-front if you had a huge amount of very predictable data).
    >
    And if, I create indexes and queries have the where
    clause and the database uses full table scans then
    does it means that either:
    The database believes that the best execution plan is
    to either do FULL SCANS OR USE INDEXES -- ALL UPTO
    THE DATABASE?
    No. There is another piece of information that the database needs to make good decisions. If for example you have a WHERE clause "WHERE not_paid = 1" and you have an index on not_paid. To make a good decision the database needs to know about how many of the rows are likely to be not_paid =1. If it's 90% then a full table scan will be cheaper than looking up the addresses of 90% of the rows and then getting the data. If it's 10% using the index will be cheaper. You need to use Analyze Tables to get the database to store this information. Looks like you need to use a bit of time with the manuals.
    Jon
    -J

  • 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

  • Query uses wrong index

    Hi,
    I have exported and imported two schemas to a different server. Now when a user fires a select query it takes more time than before. When I saw the execution plan for some of 'select' queries,I found that the queries are using wrong index.This is the reason for the delayed reponse time.
    Can anybody tell me why it happened ?
    Now what should I do?
    Can I force select query to use the right index?
    Thanx in advance

    Please find below details of the query and indexes. Do let me know if you need more information.
    Query:
    SELECT ROWID, warehouse_code, branch_code, client_code, job_srnum,
    department, inventory_date, file_no, client_carton_no, description,
    ref1, ref2, ref3, destruction_date, subject, pnw_carton_no,
    cre_user_id, cre_dt, upd_user_id, branch, upd_dt, status, date1,
    date2, num1, carton_size, addendum_date
    FROM ISTORET.rmst_inventory_details2
    WHERE branch_code = 'BOM'
    AND job_srnum = '62100113476'
    AND client_carton_no = 'BM4060394822'
    AND subject = 'FILES'
    ORDER BY file_no
    Execution Plan:
    Operation Object Name Rows Bytes Cost
    SELECT STATEMENT Optimizer Mode=CHOOSE 1 15
    SORT ORDER BY 1 155 15
    TABLE ACCESS BY INDEX ROWID ISTORET.RMST_INVENTORY_DETAILS2 1 155 5
    INDEX RANGE SCAN ISTORET.BRC_JOB_SUB_REF123_INDX 1 4
    Query time: More than 5 mins
    Same query with hint /*+ index(rmst_inventory_details2 BRC_JOB_CTN_FILE_INDX) */
    SELECT STATEMENT Optimizer Mode=CHOOSE 1 6
    TABLE ACCESS BY INDEX ROWID ISTORET.RMST_INVENTORY_DETAILS2 1 155 6
    INDEX RANGE SCAN ISTORET.BRC_JOB_CTN_FILE_INDX 1 5
    Query time: 110 msecs
    Index details:
    PARAMETER INDEX- 1 INDEX- 2
    Table Owner ISTORET ISTORET
    Table Name RMST_INVENTORY_DETAILS2 RMST_INVENTORY_DETAILS2
    Index Name BRC_JOB_CTN_FILE_INDX BRC_JOB_SUB_REF123_INDX
    Uniqueness NONUNIQUE NONUNIQUE
    Columns BRANCH_CODE
    JOB_SRNUM
    CLIENT_CARTON_NO
    FILE_NO BRANCH_CODE
    JOB_SRNUM
    SUBJECT
    REF1
    REF2
    REF3
    Table Type TABLE TABLE
    Status VALID VALID
    Tablespace ISTORET_RID2_INDX ISTORET_RID2_INDX
    Initial Extent Size 4,194,304 4,194,304
    Next Extent Size 4,194,304 4,194,304
    Minimum Extents 1 1
    Maximum Extents 2,147,483,645 2,147,483,645
    Percent Increase 0 0
    Distinct Keys 42,576,227 27,318,132
    Percent Free 10 10
    Index Type NORMAL NORMAL
    Partitioned No No
    Temporary No No
    Join Index No No
    Size in MB 2,456 2,140
    Number Extents 614 535
    Size in bytes 2,575,302,656 2,243,952,640
    Last Analyzed 20/3/2007 20/3/2007

  • Why isn't my query using the index?

    I have a query that inserts values for engines in a grid; it uses a static date table to determine the day in week, or
    week in year (depending on different standards, the DBA can configure this table to their business's likings). I have
    two indexes on this table:
    create table d_date (
         date_key number(5) not null,
         sql_calendar_date timestamp(3) null,
         year_id number(5) null,
         month_id number(3) null,
         day_id number(3) null,
         year_end_biz_date timestamp(3) null,
         qtr_end_biz_date timestamp(3) null,
         month_end_biz_date timestamp(3) null,
         week_end_biz_date timestamp(3) null,
         quarter_id number(3) null,
         week_id number(3) null,
         day_in_year number(5) null,
         day_in_month number(3) null,
         day_in_week number(3) null,
         month_name char(3) null,
         day_in_week_name char(3) null,
         month_type_code char(1) null,
         week_type_code char(1) null,
         date_type_code char(1) null,
         weekend_flag char(1) null,
         holiday_flag char(1) null,
         from_datetime timestamp(3) null,
         to_datetime timestamp(3) null,
         current_flag char(1) null,
         constraint d_date_pkey primary key (date_key)
         ) tablespace dim;
    create index d_date_dy on d_date(year_id, day_in_year) tablespace_dim_idx;
    create index d_date_ww on d_date(year_id, week_id) tablespace_dim_idx;Now, when I run a query to insert the week id into a table based on two values, the year_key and day_in_year_key,
    it should use the d_date_dy index correct?
    Here is what the query looks like:
    INSERT INTO F_ENGINE (YEAR_KEY,MONTH_KEY,WEEK_IN_YEAR_KEY,DAY_IN_YEAR_KEY,DAY_IN_MONTH_KEY,HOUR_IN_DAY_KEY, Q_HOUR_IN_DAY_KEY,
      GRID_KEY,ENGINE_KEY,TIME_STAMP,ENGINE_CPU_UTIL,ENGINE_CPU_GRID_UTIL,MEMORY_TOTAL_BYTE, MEMORY_FREE_BYTE,DISK_FREE_MEGABYTE,
      PROCESS_COUNT,ENGINE_ID,GRID_ID,GRID_NAME,BATCH_ID,RECORD_VIEWABLE_F)
    SELECT EXTRACT(YEAR FROM START_DATETIME),EXTRACT(MONTH FROM START_DATETIME), DD.WEEK_ID,
      TO_NUMBER(TO_CHAR(START_DATETIME, 'DDD')), EXTRACT(DAY FROM START_DATETIME),EXTRACT(HOUR FROM START_DATETIME),
      FLOOR(EXTRACT(MINUTE FROM START_DATETIME)/15)*15,DG.GRID_KEY,DE.ENGINE_KEY, START_DATETIME,CPU_UTIL,DS_CPU,MEMORY,
      FREE_MEMORY,FREE_DISK,PROCESSES,ID,PE.GRID,DG.GRID_NAME,:B1 ,1
    FROM P_ENGINE PE, D_GRID DG, D_ENGINE DE, D_DATE DD
    WHERE PE.GRID = DG.GRID_ID AND DG.CURRENT_FLAG = 'Y' AND PE.ID = DE.ENGINE_ID AND DE.GRID_KEY = DG.GRID_KEY AND
      DE.CURRENT_FLAG = 'Y' AND PE.BATCH_ID = :B1 AND DD.YEAR_ID = EXTRACT(YEAR FROM START_DATETIME) AND
    DD.DAY_IN_YEAR = TO_NUMBER(TO_CHAR(START_DATETIME,'DDD'))
    ORDER BY EXTRACT(YEAR FROM START_DATETIME),EXTRACT(MONTH FROM START_DATETIME),
      EXTRACT(DAY FROM START_DATETIME),EXTRACT(HOUR FROM START_DATETIME),FLOOR(EXTRACT(MINUTE FROM START_DATETIME)/15)*15,
      DG.GRID_KEY,DE.ENGINE_KEY
    Here is the explain plan:
    Operation Object Object Type Order Rows Size (KB) Cost Time (sec) CPU Cost I/O Cost
    INSERT STATEMENT
    SORT ORDER BY
         HASH JOIN
           HASH JOIN
             HASH JOIN
              TABLE ACCESS FULL D_GRID TABLE 1 2 0.316 3 1 36887 3
              TABLE ACCESS FULL D_ENGINE TABLE 2 10 0.410 3 1 42607 3
             PARTITION LIST SINGLE   5 1434 344.496 9 1 2176890 9
              TABLE ACCESS FULL P_ENGINE TABLE 4 1434 344.496 9 1 2176890 9
                TABLE ACCESS FULL D_DATE TABLE 7 7445 283.550 19 1 3274515 18Now it is obviously not using the index for the d_date table since it is doing a full table access.
    Does this have something to do with the fact that I am using extract(), to_number(), to_char() functions in my WHERE clause that it is not allowing the use of the index?
    Any help would be greatly appreciated. Thanks.
    -Tim

    It's difficult to tell just from this. For one thing, you didn't post your query using the forum format tags, so it's hard to read and you didn't post your Oracle version.
    In the query, you don't always prefix columns with the table alias. That makes it impossible for us (and maintainers of this code) to know at a glance which table a column is in.
    It's possible that performing functions on a column will disable the index. Do your other tables have indexes? Do you have updated statistics on all the tables?
    The main reason the optimizer will not use an index is because it thinks it cheaper not to.

  • How to avoid the query using the index?

    select *from cstb_cut ;
    cust_id      cust_name
    10001        xxxx
    10002        yyyy
    10003        zzzz
    Please find the above table and 10000 records are there in that table and also one index was there on cust_id.
    but my query don't want to use the index?how it will be done?

    Hi,
    DEVI suvarna wrote:
    select *from cstb_cut ;
    cust_id      cust_name
    10001        xxxx
    10002        yyyy
    10003        zzzz
    Please find the above table and 10000 records are there in that table and also one index was there on cust_id.
    but my query don't want to use the index?how it will be done?
    The index doesn't help for this query, so it's not used.
    The main purpose of indexes is the help find a small number (like 1) of rows quickly.  You're asking for all rows; getting each one through the index would be slower than just getting all of them directly.
    Sometimes (but not here) the index can be used instead of the table, when the index contains all the data you need from the table.  An index on cust_id doesn't tell you anything about any other column, such as cust_name.  Since you asked to have all columns displayed, it has to fetch data from the table, not the index.

  • Query tuning for query using connect by prior

    I have written following query to fetch the data. The query is written in this format because there are multiple rows, which make one recrd and we need to bring that record into one row.
    For one CAT(commented here), this query takes around 4 minutes and fetches 6900 records but when it runs for 3 CAT, it takes 17 mins.
    I want to tune this as this has to run for 350 CAT values.
    It is doing FTS on the main table. I tried to use different hints like PARALLEL, APPEND (in insert) but nothing worked.
    The cost of the query is 51.
    Any help/suggestions will be appreciated.
    SELECT DISTINCT MIN(SEQ) SEQ,
    PT, APP, IT, LR, QT,CD, M_A_FLAG,
    STRAGG(REM) REM, -- aggregates the data from different columns to one which is parent
    CAT
    FROM (WITH R AS (SELECT CAT, SEQ, PT, M_A_FLAG, IT, LR,QT,CD, REM, APP
    FROM table1
    WHERE REC = '36' AND M_A_FLAG = '1'
    --AND CAT = '11113')
    SELECT CAT, SEQ,
    CONNECT_BY_ROOT PT AS PT,
    CONNECT_BY_ROOT APP AS APPL,
    M_A_FLAG,
    CONNECT_BY_ROOT IT AS IT,
    CONNECT_BY_ROOT LR AS LR,
    CONNECT_BY_ROOT QT AS QT,
    CONNECT_BY_ROOT CD AS CD,
    REM
    FROM R A
    START WITH PT IS NOT NULL
    CONNECT BY PRIOR SEQ + 1 = SEQ
    AND PRIOR CAT = CAT
    AND PT IS NULL)
    GROUP BY PT, APP, IT,LR, QT, CD, M_A_FLAG, CAT
    ORDER BY SEQ;
    Thanks.
    Edited by: user2544469 on Feb 11, 2011 1:12 AM

    The following threads detail the approach and information required.
    Please gather relevant info and post back.
    How to post a SQL tuning request - HOW TO: Post a SQL statement tuning request - template posting
    When your query takes too long - When your query takes too long ...

  • Why to use a bitmap index

    I've read that it may be usefull to create a bitmap index on low cardinality columns. And this is my doubt. Let's suppose I have a gender column on a table. This certainly has got a very low cardinality 'cause I can only have M or F in it and so it could be a column to create a bitmap index on. The question is: does it make sense to create an index on such a column since probably I had better to make a full scan table having 50% of probabilities of finding a record with gender = 'F' or = 'M' rather than using an index? What I mean is that it doesn't seem to make sense creating an index on a low cardinality column, regardless of traditional or bitmap index, am I right? Therefore why and when should I learn to use bitmap indexes?
    Thanks!

    The power of bitmap indexes comes when you can combine multiple bitmaps.
    Thus, if you have multiple query predicates on the same table ANDed together, and each has a bitmap index that can be used, the optimizer can choose to do a BITMAP AND on the indexes.
    If your table has a Gender column (and only 2 (or 3 ?)) genders and queries will be only by Gender, a Bitmap index to fetch rows from the table wouldn't help. The Bitmap index can still be used to do a COUNT by Gender.
    Updating the Bitmap index on Gender would be an expensive operation so you should plan to NOT have a high rate of concurrent DML.
    Hemant K Chitale

  • 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

  • Use of Indexes in select query

    Hello,
    This is on a 9i install.
    There is an index called form_id_idx on the form_id column.
    Why does this query use the index (autotrace indicates range scan on the index):
    select count(*) from table_name where form_id=123456;
    but this query does NOT use the index (autotrace indicates full table scan):
    select accepted from table_name where form_id=123456;
    This second query runs much faster when I use a hint on the index. Any help/suggestions?
    Thanks.

    The first query does NOT have to go to the Table it all. It can read the index to count the number of rows for "form_id=123456". An Index Range Scan would be fast.
    The second query has to go to the table to get the values for the "accepted" column for all the rows that have "form_id=123456". Remember that every get can require a read of 2 or more blocks -- at least one, probably 2 or 3, from the index and 1 from the table. If the number of rows is likely to be large then the number of block get operations would be high. In such cases, Oracle computes that it is faster to do a small set of multiblock reads to read the whole table (Table FullScan).
    Therefore, the optimzer weighs :
    a. how many rows it thinks will satisfy "form_id=123456"
    b. how many index + table block gets it would have to execute (all as single block read calls to the OS)
    versus
    x. how many multiblock read calls it thinks it has to execute to read the whole table
    If the available statistics on number of rows, cardinality or density and the size of the table indicate that operation "x" would be cheaper then operations "a" + "b", Oracle would prefer the latter.
    Hemant K Chitale
    http://hemantoracledba.blogspot.com

Maybe you are looking for

  • How to set up roaming networks in both 2.4 an 5 Ghz.

    I have two Airport Extreme base stations, both separately ethernet-connected to our wired LAN. They are configured as a roaming network (both have the same SSID and security credentials). The roaming works pretty well. However, when I flip the 5 Ghz

  • Firefox wont open after update

    about 2 weeks ago i updated thunderbird and after that it would not open. i just updated firefox...it had been crashing multiple times a day...and was hoping the update would help...foolish me. now neither f-fox or t-bird will open and im stuck using

  • AppleTV unable to authorize

    This seems like a common bug. I've tried all of the "fixes" that apple suggests. Deauthorize/reauthorize, rebuild library, restore factory settings, etc. My photos will sync but any purchased content will not. Yes, I can view trailers. I'm glad that

  • Reasons to create a new class to handle mouse events

    Hi, I have a class which is very large (3000+)..anyway, some of the mouseEvents that I handle (mouseClicked, etc)...are quite large. I was thinking about separating these into a new class, but I am not 100% sure of the benefits...any suggestions, ide

  • N900 Radio player fails to load

    My device is running on the latest V 10.2010-12-9 firmware and I've the FM radio player installed, it worked fine until I done some pairing to the bluetooth, now the FM radio fails to load, I tried to uninstall and reinstall the player, also remove t