Oracle insists on using particular index in SELECT -- HELP!!!

Here's the situation:  Back in November, I wrote a report program that contained the following SELECT statement on SAP table FMIFIIT:
* Get data from the FMIFIIT table.
  SELECT trbtr
         fmbelnr
         fmbuzei
         fonds
         fistl
         farea
         measure
         fipex
         zhldt
         sgtxt
         grant_nbr
    FROM fmifiit
    INTO TABLE it_fmifiit_data
   WHERE zhldt >= p_bpdte                            AND
         zhldt <= p_epdte                            AND
         fistl IN r_fndctr                           AND
         fistl BETWEEN '4011000000' AND '4013999999' AND
         fonds IN r_fund                             AND
         fipex BETWEEN '500000' AND '599999'         AND
         measure <> 'GRANT RELEVANT'                 AND
         measure IN s_rio                            AND
         wrttp NOT IN ('51','60','81')               AND
         stats = ' '.
I ran into time-out issues with this statement, so a new index ("Z5") was created on the following fields:  ZHLDT, FISTL, FONDS, and FIPEX.  This was the 11th custom index added to the table.  The program was re-run, the statement picked up the new index, and it ran much faster.  Problem solved.
Fast-forward to this week.  I wrote a new report program that used a SELECT statement virtually identical to the one above.  It looks like this:
* Get FMIFIIT data.
  SELECT gjahr
         knbelnr
         knbuzei
         measure
         trbtr
         fmbelnr
         fmbuzei
         fonds
         fistl
         farea
         fipex
         zhldt
         sgtxt
      FROM fmifiit
      INTO TABLE it_fmifiit
   WHERE zhldt >= p_bpdte                    AND
         zhldt <= p_epdte                    AND
         fistl IN r_fndctr                   AND
         fonds IN r_fund                     AND
         fipex BETWEEN '500000' AND '599999' AND
         measure <> 'GRANT RELEVANT'         AND
         measure IN s_rio                    AND
         wrttp NOT IN ('51','60','81')       AND
         stats = ' '.
Again, the program began running into time-out issues on this statement.  I did a trace using ST05, and I found that the system was choose index "3" (FONDS, FIPEX, FIPOS) instead of the obviously-better "Z5" index created a few months ago.
I tried all kinds of things to figure out why it was choosing "3" to no avail.  Basis even re-ran statistics on the FMIFIIT table, but that didn't work.  Right now, my only option is to add an Oracle hint to the SELECT statement to force it to use index "Z5".  In our DEV system, I've used SE30 to verify that this definitely improves the timing bottleneck that occurs when "3" is used.
I've only been an ABAP programmer for a few years now, and this one is technically beyond my knowledge.  I don't know what else to try, and I don't know how to determine why the system keeps choosing the index it does.  It's especially frustrating when the SELECT statement is so similar to the one from above, and in that case, it DOES pick up the "Z5" index.
Does anyone have any information/strategies/suggestions?  At this point, I'm all ears.
Thanks so much!
Dave

Hi Dave,
based on the query I cannot share your view that there is an obvious choice.
In fact the best index choice depends on what your data looks like and how are the In-lists filled.
Maybe the range conditions are very useful, maybe the in-lists are the most selective criteria.
As a detailed analysis of this is a bit heavy to be done via this forum, why don't you just implement the hint and live happily with it?
Since you find your index sensible and have proven that it leads to better performance, you obviously know more about your data than Oracle does by the statistics.
Now you can either try and learn how the Oracle CBO works (there are notes and books available on this topic) or you just use your workaround although you may not exactly understand the reasons for the problem.
In general - if this would be a support message - I would ask you to ensure that all parameter recommendations are implemented and all CBO patches are installed.
Then I'd use the sql-statement data collection script (there's a sap note containing this script - just search for 'sql_id') to gather much of the relevant data.
And then I'd have to look into the data and figure out what's behind the CBOs decision.
As you wrote that you're rather on the ABAP side of live this effort may not necessarily be worthwhile when you have a proven workaround at hand.
regards,
Lars

Similar Messages

  • Which queries using particular index?

    Hello,
    Is it possible in Oracle 11gR2 to find out which queries are using or used particular INDEX? 
    Thanks a lot for your suggestion.
    Best Regards

    Hello,
    Thanks a lot.
    I have queried what you suggested, and got 5 sql_ids, but I quickly got the EXPLAIN PLAN for all the 5 sql_ids after getting sql_text, but the index I am looking for is not in the NAME column of select * from table (dbms_xplan.display());
    select distinct(sql_id) from v$sql_plan where object_owner = 'HEMANT' and object_name = '&myindex';
    I am little confused now, as v$sql_plan showing 5 sqls based on myindex but no one is actually using index?
    Thank you.
    Best Regards

  • 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

  • EL expression to set row at particular index as selected row

    Hi,
    What should be the EL expression to set row at index 'i' as selected row in a tree binding.
    I tried *#{bindings.treeBinding.collectionModel.selectedRow[i]}* . But it doesn't work.
    I also want to make the selected row as current. Will *#{bindings.treeBinding.collectionModel.makeCurrent}* work?
    Thanks
    KK

    Hi,
    create a managed bean that returns the selected RowKeys for the tree. See this example:
    http://www.oracle.com/technetwork/developer-tools/adf/learnmore/61search-in-rendered-trees-177577.pdf
    It searches for a specific label in a tree and marks it as selected
    Frank

  • Why is Oracle not using the index??

    Hi,
    I have a table called 'arc_errors' which has an index on 'member_number' as follows:- Create/Recreate indexes
    create index DWO.DW_ARC_CERRORS_MNO on DWO.DW_ARC_CERRORS (MEMBER_NUMBER);
    But surpisingly, when I execute the following query, it does not use the index.
    SELECT member_number,
    COUNT(*) error_count
    FROM arc_errors a
    WHERE member_number = 68534152 AND
    ( tx_type = 'SDIC' AND
    error_number IN (4, 7, 12, 13, 15, 17, 18, 705) )
    OR
    ( tx_type = 'AUTH' AND
    error_number IN (100, 104, 107, 111, 116) )
    OR
    ( tx_type = 'BHO' AND
    error_number IN (708,710) )
    OR
    ( tx_type = 'XLGN' AND
    ( error_number BETWEEN 102 AND 105 OR
    error_number BETWEEN 107 AND 120 OR
    error_number BETWEEN 300 AND 304 ) )
    OR
    ( tx_type = 'None' AND
    ( error_number IN (20, 112) OR
    error_number BETWEEN 402 AND 421 ) )
    OR
    ( tx_type = 'HYBR' AND
    error_number IN (303, 304) )
    GROUP BY member_number;
    This is what 'explain plan' tell me
    SELECT STATEMENT, GOAL = RULE               237907     502923     15087690     
    SORT GROUP BY               237907     502923     15087690     
    PARTITION RANGE ALL                              
    TABLE ACCESS FULL     DWO     DW_ARC_CERRORS     237209     502923     15087690     
    Can someone tell me why a 'table acess full' is required here?
    Thanks in advance,
    Rajesh

    Sorry, I just found the solution myself. I need to put an extra pair of braces around the set of conditions seperated by OR.

  • How to force the optimaizer to stop using an index ?

    Hello,
    I have an index on a very large table and I want to see how the applications running on this DB handles a situation in which this index does not exists.
    Therfore I have 2 options:
    1. drop the index - but this is too risky as if i will need to recreate it , it will last forever and will result in long application downtime which I can not afford.
    The test and Dev environments does not contain ammounts of data like the prodicution so its hard to predict from these environments.
    2. the second option is Modify the index columns statistics (which I have done) giving it low NDV (number of diftinct values) -- but sadly this did not work.
    when cheking event 10053 I see a the line "Using prorated density: [ 1/(2*num_rows) ] of col #n as selectivity of out-of-range value pred" which I guess meens the High value of the column is lower then the value given it the query ( I do not run statistics every day , the current statistics for all columns (execpt this one ) suits best and I do not want to handle plan changes . also it will take a lot of time to gather table stats on daily basis.
    So - to make a long story short - how do I force Oracle to avoid using an index but continue builing it and without dropping it?
    I can not use the 'NO_INDEX' hint as it will requre change in many Applications.
    I don need something like NO_INDEX hint on system level.
    I am using Oracle 10g Enterprise edition.
    the optimaized_mode is set to COST BASED.
    Thanks in advance for any help resolving this complicated issue.
    Regards,
    Amit Zor.
    ADBA.

    user3698066 wrote:
    Hello,
    I have an index on a very large table and I want to see how the applications running on this DB handles a situation in which this index does not exists.
    2. the second option is Modify the index columns statistics (which I have done)
    I'm still wondering if there is a way of modifying the statistics of the index in such a way so that it is not used by the optimizer.
    Since the main contributors of the formula for an simple b-tree index access path are the height of index, the number of leaf blocks and for the table access the clustering factor, may be you could come up with all those values bumped up to very large values for that particular index.
    Unfortunately the only component of the formula that is not multiplied by a factor is the height of the index, which is sanity checked (at least in 10.2) when set manually and is limited to a (already quite unreasonable) 255, so you can't set it greater than 255, but the remaining attributes can be set more or less to whatever you want.
    So you could come up with an manual modification of the index statistics like this. Note that I don't modify the NUM_ROWS and DISTINCT_KEYS values in an attempt to limit the risk of unwanted side effects of this modification.
    begin dbms_stats.set_index_stats(
    ownname=>'<index_owner>,
    indname=>'<index_name>',
    indlevel=>255,
    numlblks=>1000000000,
    clstfct=>1000000000,
    avglblk=>1000000000/<num_distinct>,
    avgdblk=>1000000000);
    end;
    /In a quick test I was successfully able to prevent a very selective index access path using these settings, but depending on your remaining statistics and the access paths chosen by the optimizer this might not work for you, at least not in all possible cases, e.g. an index unique scan won't cost more than 256 even using these settings because only a single leaf block by definition has to be visited in this case.
    Of course I haven't checked thoroughly what other side effects this statistics fudging does have, so use at your own risk resp. test it in your non-production environment before even thinking about applying it to an production system.
    Regards,
    Randolf
    Oracle related stuff blog:
    http://oracle-randolf.blogspot.com/
    SQLTools++ for Oracle (Open source Oracle GUI for Windows):
    http://www.sqltools-plusplus.org:7676/
    http://sourceforge.net/projects/sqlt-pp/

  • Use of Index, Histograms, etc

    Hi all,
    We're using Oracle 9.2.04.
    I have a table with 500000 rows.
    So I have a query that returns only 30242 for a month, like:
    SELECT * FROM T1
    WHERE TO_CHAR(DT, 'MM/YYYY') = TO_CHAR(ADD_MONTHS(SYSDATE, -1), 'MM/YYYY')
    I have a index for this column:
    CREATE INDEX IND_T1_DT_FMT ON T1 (TO_CHAR(DT, 'MM/YYYY'))
    TABLESPACE TBS_SOME_USER;
    There are statistics for this table.
    Looking the table data, I have the following distribution:
    Qty     MON/YY  %
    1         Feb-09     0.000219142
    99         Apr-09     0.021695016
    38439     May-09     8.42358314
    98231     Jun-09     21.52649641
    1         Jul-06     0.000219142
    139959     Jul-09     30.6708362
    1         Aug-02     0.000219142
    1         Aug-07     0.000219142
    141362     Aug-09     30.97829184
    30242     Sep-09      6.62727962
    7990              1.750941213But when a perform the query (that returns 30242 rows - 6.63% of table):
    SELECT * FROM T1
    WHERE TO_CHAR(DT, 'MM/YYYY') = TO_CHAR(ADD_MONTHS(SYSDATE, -1), 'MM/YYYY')
    Oracle uses FTS:
    0 SELECT STATEMENT Optimizer=CHOOSE (Cost=432 Card=45633 Bytes
    =3011778)
    1 0 TABLE ACCESS (FULL) OF 'T1' (Cost=432 Card=45633 Bytes
    =3011778)
    So, Oracle should not use the index in this case?
    Is there any way to gather statistics for this table with a index based function?
    Something like this:
    EXECUTE DBMS_STATS.GATHER_TABLE_STATS(ownname => 'U1',
    tabname => 'T1', method_opt => 'FOR COLUMNS TO_CHAR(DT, ''MM/YYYY'')',
    cascade => true, degree => 4);
    How can I create histograms for this case?
    Or other solution, like Partition?
    thank you very much!!!!

    Always treat dates like dates.
    This
    SELECT * FROM T1
    WHERE TO_CHAR(DT, 'MM/YYYY') = TO_CHAR(ADD_MONTHS(SYSDATE, -1), 'MM/YYYY')Should be more like this:
    SELECT * FROM T1
    WHERE DT BETWEEN TRUNC(ADD_MONTHS(SYSDATE,-1),'MM') AND TRUNC(SYSDATE,'MM')-1 ;Then you should index DT.
    But, should this query use the index?
    Touch and go at 6.63%.
    Give it a go using dates as dates and see if it makes a difference.
    Is there a problem with the performance of the FTS?

  • Restrict the use of index while quering

    Hi All
    I have a simple emp table with columns empid, name, sal. Empid has a primary key imposed.
    Now when i write a statement like this,
    select * from emp where empid = <value>;
    the optimizer will make use of index.
    The question is........... is there anyway to make oracle bypass the use of index without change in above query.

    Why do you worry of performance issues when the table size is small , when it is huge and the column you r trying use in the query is also indexed the oracle finds the Best execution method to do the execution whether index exists or not , Oracle has a very intelligent Optimizer and no need to use hints unless and until it is really mandatory or when u r using a very complex query where Oracle is not able to deduce the best Execution plan . But by all means you should look at the execution plan how a cerain query Oracle knows of doing it or when u have a diferering opinion then only at that point you force a Optomizer Hint . For other normal cases like the one you are asking it is best to get the results how Oracle executes it and no forcing is required .

  • Rule-Based Optimizer doesn4t use the index

    Does anybody know why the rule-based optimizer doesn4t use the index of all columns in the where clause?
    I have a select that use the hint RULE to force the optimizer to work in rule mode and also one index to all columns used in the where clause. Analyzing the execution plan (EXPLAIN PLAN) I observed the optimizer accesses all tables, but one, using the index. There4s one table (the first of the execution plan) that is accessed using a Full Table Scan (FTS).
    I've rebuilt the index for this table, but the execution plan doesn4t change.
    Any suggestions?
    Thanks in advance.
    Eliane.

    Hi. Oracle may not use an index if it finds that a full table scan is quicker/more efficient. Try the hint /*+ INDEX (table index) */ and compare the query performance with that of the one without this hint. (As you know, if you force Rule-based approach, the COST column in EXPLAIN PLAN output will not be populated. You may have to use trace/tkprof.)

  • Simple query but not using index..please help??

    I do have this column indexed. Why my query is not using this index?
    Any help .
    select count(*) from v_dis_sub_har;
    SQL>
      COUNT(*)
       4543289
    1 row selected.
    SQL>
    select vzw_vendor_id , count(*)
    from v_dis_sub_har
    group by vzw_vendor_id
    SQL>   2    3    4 
    VZW_VENDOR_ID   COUNT(*)
           200091     908653
           200013     908659
           200012     908659
           200057     908659
           200031     908659
    5 rows selected.
    SQL> SQL>
    explain plan for
    select
    event_seq
    from v_dis_sub_har b 
    where b.VZW_VENDOR_ID='200013'
    -- and b.status='P' and b.extract_date is null
    SQL>   2    3    4    5    6    7 
    Explained.
    SQL> SQL>
    select plan_table_output from table(dbms_xplan.display)
    SQL> SQL>   2 
    PLAN_TABLE_OUTPUT
    Plan hash value: 2852398983
    | Id  | Operation         | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT  |               |   908K|  7986K|  3132  (16)| 00:00:38 |
    |*  1 |  TABLE ACCESS FULL| V_DIS_SUB_HAR |   908K|  7986K|  3132  (16)| 00:00:38 |
    Predicate Information (identified by operation id):
    PLAN_TABLE_OUTPUT
       1 - filter("B"."VZW_VENDOR_ID"=200013)
    13 rows selected.
    SQL> SQL>

    You are right Justin. Oracle is not stupid as you may want to say some times when things do not happen according to you. I just created a bitmap index on status field and look what appened. Som times it uses bitmap index and some times it does not. And the reason is clear. Row count by status. 'S' status uses bitmap index where 'P' does not.
    Thanks for your help.
    select   status, count(*)
    from v_dis_sub_har
    group  by status
    ;SQL>   2    3    4 
    S   COUNT(*)
    A    5844982
    P    2312759
    S      20178
    3 rows selected.
    SQL>
    explain plan for
    select
    event_seq
    from v_dis_sub_har b 
    where
    --b.VZW_VENDOR_ID=200013
    --  and
    b.status='S'
    --and b.extract_date is null
    select plan_table_output from table(dbms_xplan.display)
    SQL>   2    3    4    5    6    7    8    9   10 
    Explained.
    SQL> SQL> SQL> SQL>   2 
    PLAN_TABLE_OUTPUT
    Plan hash value: 829738689
    | Id  | Operation                    | Name                         | Rows  | Bytes | Cost (%CPU)| T
    ime     |
    PLAN_TABLE_OUTPUT
    |   0 | SELECT STATEMENT             |                              | 20290 |   118K|  2772   (1)| 0
    0:00:34 |
    |   1 |  TABLE ACCESS BY INDEX ROWID | V_DIS_SUB_HAR                | 20290 |   118K|  2772   (1)| 0
    0:00:34 |
    |   2 |   BITMAP CONVERSION TO ROWIDS|                              |       |       |            |
            |
    |*  3 |    BITMAP INDEX SINGLE VALUE | V_DISPATCH_SUBSCRIPTION_NDX2 |       |       |            |
            |
    PLAN_TABLE_OUTPUT
    Predicate Information (identified by operation id):
       3 - access("B"."STATUS"='S')
    15 rows selected.
    SQL> SQL> set line 120
    SQL> /
    PLAN_TABLE_OUTPUT
    Plan hash value: 829738689
    | Id  | Operation                    | Name                         | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT             |                              | 20290 |   118K|  2772   (1)| 00:00:34 |
    |   1 |  TABLE ACCESS BY INDEX ROWID | V_DIS_SUB_HAR                | 20290 |   118K|  2772   (1)| 00:00:34 |
    |   2 |   BITMAP CONVERSION TO ROWIDS|                              |       |       |            |          |
    |*  3 |    BITMAP INDEX SINGLE VALUE | V_DISPATCH_SUBSCRIPTION_NDX2 |       |       |            |          |
    PLAN_TABLE_OUTPUT
    Predicate Information (identified by operation id):
       3 - access("B"."STATUS"='S')
    15 rows selected.
    SQL>
    explain plan for
    select
    event_seq
    from v_dis_sub_har b 
    where
    --b.VZW_VENDOR_ID=200013
    --  and
    b.status='P'
    --and b.extract_date is null
    select plan_table_output from table(dbms_xplan.display)
          SQL>   2    3    4    5    6    7    8    9   10 
    Explained.
    SQL> SQL> SQL> SQL>   2 
    PLAN_TABLE_OUTPUT
    Plan hash value: 2852398983
    | Id  | Operation         | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT  |               |  2325K|    13M|  5784  (18)| 00:01:10 |
    |*  1 |  TABLE ACCESS FULL| V_DIS_SUB_HAR |  2325K|    13M|  5784  (18)| 00:01:10 |
    Predicate Information (identified by operation id):
    PLAN_TABLE_OUTPUT
       1 - filter("B"."STATUS"='P')
    13 rows selected.
    SQL>

  • UPPER Indexes cause select ERROR!

    I downloaded Oracle 10g and installed it on a windows 2003 server. When I created UPPER indexes on a table, and the table has many rows, SELECT statement failed.
    for example:
    DROP TABLE TestTab;
    CREATE     TABLE     TestTab(
         id          NUMBER(9)     DEFAULT 1 NULL,
         name          VARCHAR2(32)     NULL,
         address          VARCHAR2(64)     NULL,
         PRIMARY     KEY     (id)
    DROP INDEX TestTab_01;
    CREATE     INDEX     TestTab_01 ON TestTab(UPPER(name));
    DROP INDEX TestTab_02;
    CREATE     INDEX     TestTab_02 ON TestTab(UPPER(address));
    create or replace procedure ADDDATA
    IS
    lCount     NUMBER;
    BEGIN
    lCount := 1;
    LOOP
    INSERT INTO TESTTAB VALUES(lCount, TO_CHAR(lCount, '00000'), TO_CHAR(lCount, '00000'));
    lCount := lCount + 1;
    IF lCount >= 80000 THEN
    EXIT;
    END IF;
    END LOOP;
    COMMIT;
    EXCEPTION
    WHEN OTHERS THEN
    ROLLBACK;
    RAISE;
    END;
    EXEC ADDDATA;
    SELECT COUNT(*) FROM TestTab;
    SELECT id FROM TestTab WHERE (UPPER(name) = ' 00100' OR UPPER(name) = ' 00101' OR UPPER(name) = ' 00102'
    OR UPPER(address) = ' 00105' OR UPPER(address) = ' 00106') ORDER BY id;
    ID
    100
    101
    102
    SELECT id FROM TestTab WHERE (UPPER(address) = ' 00105' OR UPPER(address) = ' 00106' OR UPPER(name) = ' 00100' OR UPPER(name) = ' 00101' OR UPPER(name) = ' 00102') ORDER BY id;
    ID
    105
    106
    It looks like that the first index could be used and the second index couldn't be used and indexes caused select errors.

    indexes caused select errors. Which errors ? I did exactly what you posted, and these are the results :
    TEST@db102 SQL> SELECT id FROM TestTab WHERE (UPPER(name) = ' 00100' OR UPPER(name) = ' 00101' OR UPPER(name) = ' 00102'
    OR UPPER(address) = ' 00105' OR UPPER(address) = ' 00106') ORDER BY id;  2
                 ID
                100
                101
                102
                105
                106
    TEST@db102 SQL> SELECT id FROM TestTab WHERE (UPPER(address) = ' 00105' OR UPPER(address) = ' 00106' OR UPPER(name) = ' 00100'
    OR UPPER(name) = ' 00101' OR UPPER(name) = ' 00102') ORDER BY id;
                 ID
                100
                101
                102
                105
                106
    TEST@db102 SQL> select count(*) from testtab;
           COUNT(*)
              79999
    TEST@db102 SQL>                                                                                    

  • Why is this query not using the index?

    check out this query:-
    SELECT CUST_PO_NUMBER, HEADER_ID, ORDER_TYPE, PO_DATE
    FROM TABLE1
    WHERE STATUS = 'N'
    and here's the explain plan:-
    1     
    2     -------------------------------------------------------------------------------------
    3     | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
    4     -------------------------------------------------------------------------------------
    5     | 0 | SELECT STATEMENT | | 2735K| 140M| 81036 (2)|
    6     |* 1 | TABLE ACCESS FULL| TABLE1 | 2735K| 140M| 81036 (2)|
    7     -------------------------------------------------------------------------------------
    8     
    9     Predicate Information (identified by operation id):
    10     ---------------------------------------------------
    11     
    12     1 - filter("STATUS"='N')
    There is already an index on this column, as is shown below:-
         INDEX_NAME INDEX_TYPE     UNIQUENESS     TABLE_NAME     COLUMN_NAME     COLUMN_POSITION
    1     TABLE1_IDX2 NORMAL     NONUNIQUE     TABLE1      STATUS     1
    2     TABLE1_IDX NORMAL     NONUNIQUE     TABLE1     HEADER_ID     1
    So why is this query not using the index on the 'STATUS' Column?
    I've already tried using optimizer hints and regathering the stats on the table, but the execution plan still remains the same, i.e. it still uses a FTS.
    I have tried this command also:-
    exec dbms_stats.gather_table_stats('GECS','GEPS_CS_SALES_ORDER_HEADER',method_opt=>'for all indexed columns size auto',cascade=>true,degree=>4);
    inspite of this, the query is still using a full table scan.
    The table has around 55 Lakh records, across 60 columns. And because of the FTS, the query is taking a long time to execute. How do i make it use the index?
    Please help.
    Edited by: user10047779 on Mar 16, 2010 6:55 AM

    If the cardinality is really as skewed as that, you may want to look at putting a histogram on the column (sounds like it would be in order, and that you don't have one).
    create table skewed_a_lot
    as
       select
          case when mod(level, 1000) = 0 then 'N' else 'Y' end as Flag,
          level as col1
       from dual connect by level <= 1000000;
    create index skewed_a_lot_i01 on skewed_a_lot (flag);
    exec dbms_stats.gather_table_stats(user, 'SKEWED_A_LOT', cascade => true, method_opt => 'for all indexed columns size auto');Is an example.

  • Selecting all columns makes oracle use more indexes than only selectng one?

    I have 3 queries here that differ only slightly, conceptually, but the plans are massively different. What I cant work out is that the difference is only in the select list.. The fields referenced in the where clause are properly indexed for this purpose
    SELECT
      scc.expiry_date
    FROM
      bw3.int_file_log_details  ifld
      INNER JOIN
      bw3.svc_card_status_change scsc
      USING
        (institution_number, file_number)
      INNER JOIN bw3.svc_client_cards scc
      USING
        (card_number)
    WHERE
      institution_number = '00000001' AND
      file_number = '00002504'This one above does a full table scan of SCC, over 3.5 million records
    SELECT
      card_number
    FROM
      bw3.int_file_log_details  ifld
      INNER JOIN
      bw3.svc_card_status_change scsc
      USING
        (institution_number, file_number)
      INNER JOIN bw3.svc_client_cards scc
      USING
        (card_number)
    WHERE
      institution_number = '00000001' AND
      file_number = '00002504'This one above does an index fast full scan of SCC's pk (which is cardnumber), as does doing a "SELECT null as dummy FROM..."
    SELECT
    FROM
      bw3.int_file_log_details  ifld
      INNER JOIN
      bw3.svc_card_status_change scsc
      USING
        (institution_number, file_number)
      INNER JOIN bw3.svc_client_cards scc
      USING
        (card_number)
    WHERE
      institution_number = '00000001' AND
      file_number = '00002504'This one above does the index range scan of the columns mentioned in the where clause and two index unique scans to link in IFLD and SCC (because they are joined on their PKs)
    I would expect all queries to run this way and completes in ~0.01 seconds
    Now, I get that oracle will sometimes use only an index instead of a table access when the requested data can be got from the index, but the actual query is pulling data from some columns not in indexes, so must be accessed in the table:
    SELECT
      scsc.card_prod_data as "Field1",
      substr(card_number,1,4)||' '||
        substr(card_number,5,4)||' '||
        substr(card_number,9,4)||' '||
        substr(card_number,13,4)||' '||
        substr(card_number,17) as "Field2",
      '                           ' as "Field3",
      scc.emboss_line_1 as "Field4",
      scc.emboss_line_2 as "Field5",
      TO_CHAR(TO_DATE(scc.last_issued_date, 'YYYYMMDD'), 'MM/YY ')||
        TO_CHAR(TO_DATE(scc.expiry_date, 'YYYYMMDD'), 'MM/YY  ')||
        '    ' as "Field6",
      'B'||
        card_number||
        '^'||
        RPAD('0', 27, ' ')||
        '^'||
        to_char(to_date(scc.expiry_date, 'YYYYMMDD'), 'YYMM')||
        service_category_code||
        '000000000000' as "Field7",
      card_number||
        '='||
        to_char(to_date(scc.expiry_date, 'YYYYMMDD'), 'YYMM')||
        service_category_code||
        '000000000000' as "Field8",
      card_number as "Field9",
      scsc.cvv_cvc2 as "Field10"
    FROM
      bw3.int_file_log_details  ifld
      INNER JOIN
      bw3.svc_card_status_change scsc
      USING
        (institution_number, file_number)
      INNER JOIN bw3.svc_client_cards scc
      USING
        (card_number)
    WHERE
      institution_number = '00000001' AND
      file_number = '00002504'This query above, which uses some data from all tables, does a table full scan of SCC, yet if I SELECT * FROM.. I get the expected index usage and table access by index rowid for all tables..
    Why is oracle doing an FTS when I choose only some columns, yet doing index access when I select * ?
    Edited by: charred on Oct 5, 2010 11:37 AM

    Selectivity of indexes?
    For a query linking these tables:
    int_file_log_details <-> svc_card_status_change <-> svc_client_cards
    I'm expecting Oracle to:
    Use an index range scan of the index on svc_card_status_change that is a nonunique index of institution_number and file number. Selectivity of this index is:
    1 institution number in the entire table
    59 distinct file numbers in the entire table
    4.1million records in the entire table
    From there, with the records it found, to use index unique scan of the PKs of int_file_log_details (file_number: 1 record required) and PK of svc_client_cards (card_number: poetntially thousands of records required)
    I can understand if oracle might decide it can get 69k records out of 4.1 million faster by FTS the cards table rather than having the indirection of the index... what I cannot understand is:
    If I select all the data from the query (SELECT *) it does unique index scans for the 2 records
    If I select say, only one non-indexed non-joined column from each table, oracle prefers a FTS of the cards table..
    Is oracle not realising that there are only 2 records I need out of cards? Why would select * differ? Is it that oracle thinks "select * is a large amount of data, so it'll be faster to use the index and target certain rows" vs "select one_column can be garnered more quickly by scanning the table and generating a lower overall memory load" ?

  • How to specify a particular index for DB2 database when using SQL in ABAP

    Is this format for Oracle?
      select *
       into -
       from  vbrk CLIENT SPECIFIED
    where erdat in erdat
        and mandt EQ sy-MANDT
        %_HINTS ORACLE 'INDEX("VBRK" "VBRK~ZER")'
    For the index 'VBRK~ZER' was defined before,it only includes one field 'VBRK-ERDAT'.
    How can i tell Sap to use this index while processing SQL in DB2?
    Thanks advance.

    There are different hints for the different database platforms.
    For up-to-date information please read the SAP notes, search 'hint DB2'.
    Siegfried

  • How to prevent Oracle from using an index when joining two tables ...

    How to prevent Oracle from using an index when joining two tables to get an inline view which is used in an update statement?
    O.K. I think I have to explain what I mean:
    When joining two tables which have many entries sometimes it es better not to use an index on the column used as join criteria.
    I have two tables: table A and table B.
    Table A has 4.000.000 entries and table B has 700.000 entries.
    I have a join of both tables with a numeric column as join criteria.
    There is an index on this column in table A.
    So I instead of
      where (A.col = B.col)I want to use
      where (A.col+0 = B.col)in order to prevent Oracle from using the index.
    When I use the join in a select statement it works.
    But when I use the join as inline view in an update statement I get the error ORA-01779.
    When I remove the "+0" the update statement works. (The column col is unique in table B).
    Any ideas why this happens?
    Thank you very much in advance for any help.
    Regards Hartmut

    I think you should post an properly formatted explain plan output using DBMS_XPLAN.DISPLAY including the "Predicate Information" section below the plan to provide more details regarding your query resp. update statement. Please use the \[code\] and \[code\] tags to enhance readability of the output provided:
    In SQL*Plus:
    SET LINESIZE 130
    EXPLAIN PLAN FOR <your statement>;
    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);Usually if you're using the CBO (cost based optimizer) and have reasonable statistics gathered on the database objects used the optimizer should be able to determine if it is better to use the existing index or not.
    Things look different if you don't have statistics, you have outdated/wrong statistics or deliberately still use the RBO (rule based optimizer). In this case you would have to use other means to prevent the index usage, the most obvious would be the already mentioned NO_INDEX or FULL hint.
    But I strongly recommend to check in first place why the optimizer apparently seems to choose an inappropriate index access path.
    Regards,
    Randolf
    Oracle related stuff:
    http://oracle-randolf.blogspot.com/
    SQLTools++ for Oracle:
    http://www.sqltools-plusplus.org:7676/
    http://sourceforge.net/projects/sqlt-pp/

Maybe you are looking for

  • PR/PO Controlling Using FM

    We're trying to control PR/PO creation using Funds Management. Right now we're doing the basic FM setup (following buidling block configuration guide 951 - Funds Management-Basic Settings). Can someone please outline the necessary steps to achieve th

  • List of issues with WSCompile

    Hi, Please let me know if there are any solutions to this or any forum topics relating to this. 1) Wscompile doesn't understand abstract="true". So the generated java source is not an abstract class.   <complexType name="WSMessage" abstract="true"> W

  • T430 DisplayPort doesn't show pre-boot display

    We have T430's (and X230's for that matter) connected to L2251x's via a Mini Dock Plus 3. We also have McAfee SafeBoot installed, which has a pre-boot password prompt before hitting the Windows 7 OS. No matter what we do, we cannot output this pre-bo

  • Iphone is disabled connect to itunes iphone 5

    iphone is disabled connect to itunes iphone 5

  • Year to date of epoch time

    I am doing a report where I would like to select records year to date. My difficulty is that the date field is in epoch time from 1/1/1990. What would be the formula for this record selection? I know I could use yeartodate and dateadd but am having t