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

Similar Messages

  • 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

  • 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

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

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

  • Using to_date causes CBO to use wrong index

    I'm working on switching an application from using the Rule-based optimizer to use the Cost-based Optimizer on Oracle 9iR2. I'm having problems with the following query:
    select report_rsn, reports.facility_code,
           exams.facility_code
      from exams join reports using (report_rsn)
    where reports.transcribed_date
            between to_date('17-Mar-2005')
                and to_date('18-Mar-2005')
       and exams.dictated_for_rsn = 3323
       and exams.status IN ('S','T')There is an index on the reports.transcribed_date column and a compound index on (exams.dictated_for_rsn,exams.status).
    EXPLAIN PLAN tells me this query will use the transcribed_date as the driving index, but when I run the query through SQL_TRACE, tkprof says that it used the other index instead. That took a long time. (90 seconds)
    If I change the to_date() functions to be ANSI date literals (DATE '2005-03-17' and DATE '2005-03-18'), EXPLAIN PLAN says the same as before, and tkprof says that it actually used that plan. The query returned almost instantly.
    We have CURSOR_SHARING set to 'SIMILAR', and my best guess is that there is something involving the "bind parameter peeking" that is causing the problem. It appears as if the optimizer does not evaluate the to_date() function between "peeking" at the bind variable and determining the execution plan, so it does not know that the two dates are only a day apart. However, I haven't been able to find anything in the docs to confirm my suspicions.
    I've done a search for queries in our system that use the to_date() function as part of the where clause, and it doesn't look like a Herculean task to simply change them all, but I'm wondering two things:
    1) Is there a better way to solve the problem?
    2) Is there any information on this behavior out there that I can read to verify my suspicions? This might be the most important, because in order to finalize the switch to CBO, I need to be able to tell my supervisor that "this sort of thing" won't happen on our production box.
    -- Jeff Beal

    Jeff,
    Could you post your plan under both scenarios? WhatHere are the relevant* (different) portions of the execution plan (as given by TKPROF):
    * I actually ran TKProf against a much larger query, but the controlling part is the query that I included.
    When using DATE literal:
    Rows     Row Source Operation
          0               NESTED LOOPS 
          0                TABLE ACCESS BY INDEX ROWID REPORTS
          6                 INDEX RANGE SCAN IX_REPORTS_TRDATE (object id 109215)
          0                TABLE ACCESS BY INDEX ROWID EXAMS
          0                 INDEX RANGE SCAN IX_FK_EXAMS_11 (object id 96878)When using to_date function
    Rows     Row Source Operation
      46517                NESTED LOOPS 
      46517                 INLIST ITERATOR 
      46517                  TABLE ACCESS BY INDEX ROWID EXAMS
      46517                   INDEX RANGE SCAN IX_FK_EXAMS_4 (object id 139880)
          0                 TABLE ACCESS BY INDEX ROWID REPORTS
      46517                   INDEX UNIQUE SCAN PK_REPORTS (object id 109164)
    are the indexes on the tables and on what columns are
    they present?'ix_fk_exams_4' is a compound index on the exams table.  The first column is 'dictated_for_rsn' and the second is 'status'.  'pk_reports' is an index on reports.report_rsn - the primary key of the table.  'ix_reports_trdate' is on the reports.transcribed_date column.  'ix_fk_exams_11' is on exams.report_rsn (the foreign key to the reports table).
    Just to give you an idea on size, the exams table has about six million rows; the reports table has about 5.5 million.  I would categorize the transcribed_date column as evenly distributed, along with the values in dictated_for_rsn.  The status column is heavily skewed, with 'T' and 'S' being the two most common statuses.

  • 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

  • Spatial Query not using Spatial Index

    Hi All,
    I have a query which uses the SDO_WITHIN_DISTANCE operator, but is taking far too long to complete.
    SELECT
                   RT.*,RD.RPD_NODE_ID, RD.RPD_XCOORD,RD.RPD_YCOORD
              FROM
                   railplan_data RD
                   LEFT JOIN Walk_data_sets WDS ON RD.RPD_RPS_ID = WDS.WDS_RPS_ID
                   LEFT JOIN RWNet_Temp RT ON WDS.WDS_ID = RT.RW_WDS_ID
              WHERE
                   WDS.wds_id = 441
              AND
                   MDSYS.SDO_WITHIN_DISTANCE(RT.RW_GEOM,RD.RPD_GEOLOC,'DISTANCE=' || TO_CHAR(RT.RW_BUFFER) || ' UNIT=METER') = 'TRUE';
    Upon generation of the explain plan I have realised that the spatial index is not being used in the query, but I can't for the life of me get the thing working
    3     | Id | Operation | Name | Rows | Bytes |TempSpc| Cost |
    4     ------------------------------------------------------------------------------------------
    5     | 0 | SELECT STATEMENT | | 25841 | 99M| | 201 |
    6     |* 1 | FILTER | | | | | |
    7     | 2 | MERGE JOIN OUTER | | | | | |
    8     |* 3 | HASH JOIN | | 12652 | 420K| 2968K| 185 |
    9     | 4 | TABLE ACCESS FULL | RAILPLAN_DATA | 75910 | 2075K| | 60 |
    10     | 5 | TABLE ACCESS BY INDEX ROWID| WALK_DATA_SETS | 1 | 6 | | 1 |
    11     |* 6 | INDEX UNIQUE SCAN | WDS_PK | 1 | | | |
    12     |* 7 | SORT JOIN | | 16 | 63760 | | 16 |
    13     |* 8 | TABLE ACCESS FULL | RWNET_TEMP | 16 | 63760 | | 4 |
    If anyone could help me out in figuring out why the spatial index is not being used, I would be most appreciative.
    TIA
    Dan

    Hi all again,
    Well I finally got an upgrade to Oracle 10 (yay!), so I am now trying to implement the SDO_JOIN method as per my earlier posts. In fact it is actually working, but I have a question. When I run an explain plan it does not show the use of any domain indexes which I would expect to see, but performs fine (1.07s) with just a few records (10 in 1 table, 15000 in the other), please see code and explain plan below:
    SELECT
      Distinct
        RT.RW_ID, RD.RPD_NODE_ID,
        RD.RPD_XCOORD,RD.RPD_YCOORD
    FROM
        RPD_TEMP_762 RD,
        WALK_DATA_SETS WDS,
        RWNET_TEMP RT,
        TABLE
        (SDO_JOIN
            (  'RWNET_TEMP',
                'RW_GEOM',
                'RPD_TEMP_762',
                'RPD_GEOLOC',
                'distance= ' || TO_CHAR(RT.RW_BUFFER) || ' unit=meter')) SPATIAL_JOIN_RESULT
    WHERE WDS.WDS_ID = RT.RW_WDS_ID
    AND WDS.WDS_ID = 762
    AND SPATIAL_JOIN_RESULT.ROWID1 = RT.ROWID
    AND SPATIAL_JOIN_RESULT.ROWID2 = RD.ROWID
    PLAN_TABLE_OUTPUT                                                                                                                                                                                                                                                                                           
    | Id  | Operation                            | Name         | Rows  | Bytes | Cost (%CPU)|                                                                                                                                                                                                                  
    |   0 | SELECT STATEMENT                     |              |    74 |  5994 | 21753   (1)|                                                                                                                                                                                                                  
    |   1 |  SORT UNIQUE                         |              |    74 |  5994 | 21691   (1)|                                                                                                                                                                                                                  
    |*  2 |   HASH JOIN                          |              |  1046K|    80M|  1859   (1)|                                                                                                                                                                                                                  
    |   3 |    NESTED LOOPS                      |              |  6076 |   213K|  1824   (1)|                                                                                                                                                                                                                  
    |   4 |     NESTED LOOPS                     |              |    74 |  2516 |   194   (1)|                                                                                                                                                                                                                  
    |*  5 |      INDEX UNIQUE SCAN               | WDS_PK       |     1 |     4 |     0   (0)|                                                                                                                                                                                                                  
    |*  6 |      TABLE ACCESS FULL               | RWNET_TEMP   |    74 |  2220 |   194   (1)|                                                                                                                                                                                                                  
    |*  7 |     COLLECTION ITERATOR PICKLER FETCH| SDO_JOIN     |       |       |            |                                                                                                                                                                                                                  
    |   8 |    TABLE ACCESS FULL                 | RPD_TEMP_762 | 17221 |   756K|    28   (0)|                                                                                                                                                                                                                  
    ------------------------------------------------------------------------------------------  When i try to add hints to force the use of spatial indexes the performance of this query drops through the floor (it takes minutes / hours), index hint shown below:
    /*+ ORDERED INDEX(RW rw_geom) INDEX(RD rpd_geoloc) */My question is is the first query using domain indexes, and if not, how do I get it to?
    TIA
    Dan

  • Wrong index usage in execution plan

    I have one large document in container created with DBXML_INDEX_NODES flag.
    There is an index by "high" attribute node
    self.container.addIndex ( "", "high", "edge-attribute-equality-double", self.uc )
    About 50% of elements in document have structure:
    <record><data high="XX.XX" /></record>
    Which are inside "session" element which is itself inside "log" element. Only one "log" and one "session" element exist in document
    Index by “high” attribute node is very selective. Below is execution plan (changing index to "node" doesn't change things). Index is used on "presence" of "high" attribute and not "value" of it. I think using it for value would improve the speed of the query. Here is the query produced the execution plan below "collection ( 'test.dbxml' )/log/session/record[data/@high=79.37]"
    <XQuery>
    <Navigation>
    <QueryPlanFunction result="collection" container="seasonal.dbxml">
    <OQPlan>P(edge-attribute-equality-double,prefix,data.@high)</OQPlan>
    </QueryPlanFunction>
    <Step axis="child" name="log" nodeType="element"/>
    <Step axis="child" name="session" nodeType="element"/>
    <Step axis="child" name="record" nodeType="element"/>
    <DbXmlFilter>
    <Navigation>
    <Step axis="child" name="data" nodeType="element">
    <OQPlan>P(edge-attribute-equality-double,prefix,data.@high)</OQPlan>
    </Step>
    <Step axis="attribute" name="high" nodeType="attribute"/>
    <DbXmlCompare name="equal">
    <OQPlan>P(edge-attribute-equality-double,prefix,@high)</OQPlan>
    <Sequence>
    <AnyAtomicTypeConstructor value="79.37" typeuri="http://www.w3.org/2001/XMLSchema" typename="decimal"/>
    </Sequence>
    </DbXmlCompare>
    </Navigation>
    </DbXmlFilter>
    </Navigation>
    </XQuery>
    Also, why is the “typename” attribute of “AnyAtomicTypeConstructor” element is “decimal”?
    Removing flag DBXML_INDEX_NODES on the container increases speed significantly and produces this execution plan, speed is not acceptable though.
    <XQuery>
    <Navigation>
    <QueryPlanFunction result="collection" container="seasonal.dbxml">
    <OQPlan>P(edge-attribute-equality-double,prefix,data.@high)</OQPlan>
    </QueryPlanFunction>
    <Step axis="child" name="log" nodeType="element"/>
    <Step axis="child" name="session" nodeType="element"/>
    <Step axis="child" name="record" nodeType="element"/>
    <DbXmlFilter>
    <Navigation>
    <Step axis="child" name="data" nodeType="element"/>
    <Step axis="attribute" name="high" nodeType="attribute"/>
    <DbXmlCompare name="equal">
    <Sequence>
    <AnyAtomicTypeConstructor value="79.37" typeuri="http://www.w3.org/2001/XMLSchema" typename="decimal"/>
    </Sequence>
    </DbXmlCompare>
    </Navigation>
    </DbXmlFilter>
    </Navigation>
    </XQuery>
    Using index lookup allows achieving speed I need. I'd like to know how to properly write the query and what index to use in my case, though.

    Your query is not using the index because the numeric literal you are using is an xs:decimal, not an xs:double. Wrapping your literal in a cast should make the query use your index:
    collection ( 'test.dbxml' )/log/session/record[data/@high=xs:double(79.37)]
    Having said that, this is only the case for DB XML 2.2.13 and before. It turns out that DB XML has been choosing the wrong type to perform comparisons under - and this has been remedied in the forthcoming version. In your case, the new behaviour will mean that the comparison will always be performed as an xs:double.
    John

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

  • Use of Index although a great number of rows is returned....

    Hi ,
    I have created the following table:
    create table all_obj select * from all_objects;
    Then i created some indexes:
    create index idx_obj on all_obj (object_name)
    create index idx_owner on all_obj (owner)
    Then i issued the sql statement:
    SQL> select count(object_name),owner from all_obj group by owner;
    COUNT(OBJECT_NAME) OWNER
                   719 MDSYS
                   266 SCOTT_BI
                   266 INFO_BI
                     2 TSMSYS
                   118 DMSYS
    20146 PUBLIC
                     6 OUTLN
                   171 CTXSYS
                   612 OLAPSYS
                   400 SYSTEM
                   168 EXFSYS
    43 SCOTT
                    32 DBSNMP
                  1638 ORDSYS
                     5 ORDPLUGINS
                   866 SYSMAN
                   284 XDB
    20993 SYS
                   264 INFORMATICS
                   212 WMSYS
    COUNT(OBJECT_NAME) OWNER
                     8 SI_INFORMTN_SCHEMA
    21 rows selectedand...:
    SQL> analyze table all_obj compute statistics;
    Table analyzedAt last , i issued the following pair of sql statements:
    SQL> select object_name,owner from scott.all_obj where owner='SCOTT'
      2  /
    43 ãñáììÝò åðéëÝ÷èçêáí.
    Ðñüãñáììá åêôÝëåóçò
    Plan hash value: 2272571446
    | Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| T
    ime     |
    |   0 | SELECT STATEMENT            |           |  2249 | 65221 |    68   (0)| 0
    0:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| ALL_OBJ   |  2249 | 65221 |    68   (0)| 0
    0:00:01 |
    |*  2 |   INDEX RANGE SCAN          | IDX_OWNER |  2249 |       |     6   (0)| 0
    0:00:01 |
    Predicate Information (identified by operation id):
       2 - access("OWNER"='SCOTT')
    ÓôáôéóôéêÜ
              0  recursive calls
              0  db block gets
             12  consistent gets
              0  physical reads
              0  redo size
           1692  bytes sent via SQL*Net to client
            407  bytes received via SQL*Net from client
              4  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             43  rows processedand
    SQL> select object_name,owner from scott.all_obj where owner='SYS';
    20993 ãñáììÝò åðéëÝ÷èçêáí.
    Ðñüãñáììá åêôÝëåóçò
    Plan hash value: 2272571446
    | Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| T
    ime     |
    |   0 | SELECT STATEMENT            |           |  2249 | 65221 |    68   (0)| 0
    0:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| ALL_OBJ   |  2249 | 65221 |    68   (0)| 0
    0:00:01 |
    |*  2 |   INDEX RANGE SCAN          | IDX_OWNER |  2249 |       |     6   (0)| 0
    0:00:01 |
    Predicate Information (identified by operation id):
       2 - access("OWNER"='SYS')
    ÓôáôéóôéêÜ
              0  recursive calls
              0  db block gets
           3345  consistent gets
              0  physical reads
              0  redo size
         801069  bytes sent via SQL*Net to client
          15774  bytes received via SQL*Net from client
           1401  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
          20993  rows processed
    The question is: why the second query uses the index since a great number of records is returned......????
    I use Oracle10g.v.2
    Thanks...
    Sim

    You were right.....
    using:
    SQL> EXEC DBMS_STATS.gather_schema_stats(ownname => 'SCOTT');
    the optimizer does follow the 'waited' access path....for the 'PUBLIC' records.....
    It seems that using the analyze table statement does not permit to gather all the necessary statistics.....(that's why it is depreciated)...!!!!
    Thanks.....
    Sim

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

  • Does an 'in' clause use the index?

    In the following query:
    Select * from myTable where field_1 in ('thisfield', 'thatfield');
    Assuming there is an index on field_1, will this query use the index?
    Thanks,
    Sara

    In the following query:
    Select * from myTable where field_1 in ('thisfield', 'thatfield');
    Assuming there is an index on field_1, will this query use the index?It should use the index to find where the row you want is in the table and then access the table to return all colunms for that row.
    This can be easily verified by doing an explain plan on your SQL statement. The Oracle manuals should have information on how to
    run an explain plan if you're not familiar with it.

  • Query using progressive relaxation take more time for execution

    HI Gurus,
    I am creating a query using context index and progressive relaxation
    I had started using progressive relaxation after getting inputs from forum {thread:id=2333942} . Using progressive relaxation takes more than 7 seconds for every query. Is there any way we can improve the performance of the query?
    create table test_sh4 (text1 clob,text2 clob,text3 clob);
    begin
       ctx_ddl.create_preference ('nd_mcd', 'multi_column_datastore');
       ctx_ddl.set_attribute
          ('nd_mcd',
           'columns',
           'replace (text1, '' '', '''') nd1,
            text1 text1,
            replace (text2, '' '', '''') nd2,
            text2 text2');
       ctx_ddl.create_preference ('test_lex1', 'basic_lexer');
       ctx_ddl.set_attribute ('test_lex1', 'whitespace', '/\|-_+');
       ctx_ddl.create_section_group ('test_sg', 'basic_section_group');
       ctx_ddl.add_field_section ('test_sg', 'text1', 'text1', true);
       ctx_ddl.add_field_section ('test_sg', 'nd1', 'nd1', true);
       ctx_ddl.add_field_section ('test_sg', 'text2', 'text2', true);
       ctx_ddl.add_field_section ('test_sg', 'nd2', 'nd2', true);
    end;
    create index IX_test_sh4 on test_sh4 (text3)   indextype is ctxsys.context   parameters    ('datastore     nd_mcd   lexer test_lex1 section group     test_sg') ;
    alter index IX_test_sh4 REBUILD PARAMETERS ('REPLACE SYNC (ON COMMIT)') ;-- sync index on every commit.
    SELECT SCORE(1) score,t.* FROM test_sh4 t WHERE CONTAINS (text3,  '
    <query>
    <textquery>
    <progression>
    <seq>{GIFT GRILL STAPLES CARD} within text1</seq>
    <seq>{GIFTGRILLSTAPLESCARD} within nd1</seq>
    <seq>{GIFT GRILL STAPLES CARD} within text2</seq>
    <seq>{GIFTGRILLSTAPLESCARD} within nd2</seq>
    <seq>((%GIFT% and %GRILL% and %STAPLES% and %CARD%)) within text1</seq>
    <seq>((%GIFT% and %GRILL% and %STAPLES% and %CARD%)) within text2</seq>
    <seq>((%GIFT% and %GRILL% and %STAPLES%) or (%GRILL% and %STAPLES% and %CARD%) or (%GIFT% and %STAPLES% and %CARD%) or (%GIFT% and %GRILL% and %CARD%)) within text1</seq>
    <seq>((%GIFT% and %GRILL% and %STAPLES%) or (%GRILL% and %STAPLES% and %CARD%) or (%GIFT% and %STAPLES% and %CARD%) or (%GIFT% and %GRILL% and %CARD%)) within text2</seq>
    <seq>((%STAPLES% and %CARD%) or (%GIFT% and %GRILL%) or (%GRILL% and %CARD%) or (%GIFT% and %CARD%) or (%GIFT% and %STAPLES%) or (%GRILL% and %STAPLES%)) within text1</seq>
    <seq>((%STAPLES% and %CARD%) or (%GIFT% and %GRILL%) or (%GRILL% and %CARD%) or (%GIFT% and %CARD%) or (%GIFT% and %STAPLES%) or (%GRILL% and %STAPLES%)) within text2</seq>
    <seq>((%GIFT% , %GRILL% , %STAPLES% , %CARD%)) within text1</seq>
    <seq>((%GIFT% , %GRILL% , %STAPLES% , %CARD%)) within text2</seq>
    <seq>((!GIFT and !GRILL and !STAPLES and !CARD)) within text1</seq>
    <seq>((!GIFT and !GRILL and !STAPLES and !CARD)) within text2</seq>
    <seq>((!GIFT and !GRILL and !STAPLES) or (!GRILL and !STAPLES and !CARD) or (!GIFT and !STAPLES and !CARD) or (!GIFT and !GRILL and !CARD)) within text1</seq>
    <seq>((!GIFT and !GRILL and !STAPLES) or (!GRILL and !STAPLES and !CARD) or (!GIFT and !STAPLES and !CARD) or (!GIFT and !GRILL and !CARD)) within text2</seq>
    <seq>((!STAPLES and !CARD) or (!GIFT and !GRILL) or (!GRILL and !CARD) or (!GIFT and !CARD) or (!GIFT and !STAPLES) or (!GRILL and !STAPLES)) within text1</seq>
    <seq>((!STAPLES and !CARD) or (!GIFT and !GRILL) or (!GRILL and !CARD) or (!GIFT and !CARD) or (!GIFT and !STAPLES) or (!GRILL and !STAPLES)) within text2</seq>
    <seq>((!GIFT , !GRILL , !STAPLES , !CARD)) within text1</seq>
    <seq>((!GIFT , !GRILL , !STAPLES , !CARD)) within text2</seq>
    <seq>((?GIFT and ?GRILL and ?STAPLES and ?CARD)) within text1</seq>
    <seq>((?GIFT and ?GRILL and ?STAPLES and ?CARD)) within text2</seq>
    <seq>((?GIFT and ?GRILL and ?STAPLES) or (?GRILL and ?STAPLES and ?CARD) or (?GIFT and ?STAPLES and ?CARD) or (?GIFT and ?GRILL and ?CARD)) within text1</seq>
    <seq>((?GIFT and ?GRILL and ?STAPLES) or (?GRILL and ?STAPLES and ?CARD) or (?GIFT and ?STAPLES and ?CARD) or (?GIFT and ?GRILL and ?CARD)) within text2</seq>
    <seq>((?STAPLES and ?CARD) or (?GIFT and ?GRILL) or (?GRILL and ?CARD) or (?GIFT and ?CARD) or (?GIFT and ?STAPLES) or (?GRILL and ?STAPLES)) within text1</seq>
    <seq>((?STAPLES and ?CARD) or (?GIFT and ?GRILL) or (?GRILL and ?CARD) or (?GIFT and ?CARD) or (?GIFT and ?STAPLES) or (?GRILL and ?STAPLES)) within text2</seq>
    <seq>((?GIFT , ?GRILL , ?STAPLES , ?CARD)) within text1</seq>
    <seq>((?GIFT , ?GRILL , ?STAPLES , ?CARD)) within text2</seq>
    </progression>
    </textquery>
    <score datatype="FLOAT" algorithm="default"/>
    </query>',1) >0 ORDER BY score(1) DESC

    Progressive relaxation works best when you're only selecting a limited number of rows. If you fetch ALL the rows which satisfy the query, then all the steps in the relaxation will have to run regardless.
    If you fetch - say - the first 10 results, then if the first step of the relaxation provides 10 results then there is no need to execute the next step (in fact, due to internal buffering, that won't be exactly true but it's conceptually correct).
    The simplest way to do this is reword the query as
    SELECT * FROM (
    ( SELECT SCORE(1) score,t.* FROM test_sh4 t WHERE CONTAINS (text3, '
    <query>
    <textquery>
    </textquery>
    <score datatype="FLOAT" algorithm="default"/>
    </query>',1) >0 ORDER BY score(1) DESC
    WHERE ROWNUM <= 10
    You've discovered that leading wild cards don't work too well unless you use SUBSTRING_INDEX. I would encourage you to avoid them altogether if possible, or push them down much lower in the progressive relaxation. Usually, GIFT% is a useful expression (matches GIFTS, GIFTED, etc), %GIFT% is generally no more effective.
    There are a lot of steps in your progressive relaxation. It you wanted to reduce the number of steps, you could change:
    <seq>((%GIFT% and %GRILL% and %STAPLES% and %CARD%)) within text1</seq>
    <seq>((%GIFT% and %GRILL% and %STAPLES% and %CARD%)) within text2</seq>
    to
    <seq>((%GIFT% and %GRILL% and %STAPLES% and %CARD%)*2) within text1 ACCUM ((%GIFT% and %GRILL% and %STAPLES% and %CARD%)) within text2</seq>
    I don't know if this would have any performance benefits - but it's worth trying it to see.

Maybe you are looking for

  • Re : Payment Terms 40 days due on 10 th month

    Needs Payment Term Configuration  : Payment Terms 40 days due on 10 th month Regards Chandu

  • Issue in Deploying application in Weblogic 10 3 3 + Oracle JRockit(R) R28.1

    Hi I have Weblogic 10 3 3 with Oracle JRockit(R) R28.1.0-123-138454-1.6.0_20-20101014-1350-linux-ia32 as my JVM on my Linux box. When I deploy my application and starts it, app goes to New state and my Managed servers (on which I deploy my app) are f

  • Connecting FW400 disconnects FW800 device

    I bought a 2 bay FW 800 drive box which uses the Oxford 924dsb which is a highly regarded chipset from what I have read. I use one drive for Time Machine, the other was to be for video capture. I have captured from my FW 400 DV camcorder successfully

  • Screen black, backlight on, external on

    Hi, So I've been reading a similar forum only mine is slightly different. I have it hooked up to a 19" external display, and that works fine. The problem is when I disconnect from the display and use it as a laptop. Everything would be fine for some

  • Updating my 24" imac

    hey i attempted to update my imac, although i dont think it went according to plan, upon start up i get a textedit telling me; launch.command #!/bin/bash echo "Process Id: $$" cd /tempwiz nohup ./stRelauncher /Volumes/STRESv6103/stInstall.app & id=`p