Dblink + local function: INDEX RANGE SCAN not used

Hi All,
I have an sql query to remote database:
SELECT N FROM [email protected] WHERE cd_n = 60
It works with INDEX RANGE SCAN for "N" field of table "tab", it's ok.
Now I'm replacing the constant value with the local database function:
SELECT N FROM [email protected] WHERE cd_n = dannis.foo()
Then 'INDEX RANGE SCAN' is removed out from query execution plan :-(
I've tried some tricks as
/*+ rule index(user.tab TAB$PK) */,
driving_site(tab),
to_number(dannis.foo()),
(select dannis.foo from [email protected])
and so on...
but INDEX RANGE SCAN wasn't appear while using the local function.
Is it true when dblink is used in combination with local function then INDEX RANGE SCAN will never used?
/Oracle 9.0.1.2/
Thanx,
dannis.

See Optimizer not taking the hint

Similar Messages

  • Index range scan cost change in 10.2.0.1

    SQL> create table t1 as
    2 select
    3 rpad('x',40) ind_pad,
    4 trunc(dbms_random.value(0,25)) n1,
    5 trunc(dbms_random.value(0,25)) n2,
    6 lpad(rownum,10,'0') small_vc,
    7 rpad('x',200) padding
    8 from
    9 all_objects
    10 where
    11 rownum <= 10000
    12 ;
    Table created.
    SQL> create index t1_i1 on t1(ind_pad,n1,n2)
    2 pctfree 91
    3 ;
    Index created.
    SQL> set autot trace exp
    SQL> alter session set optimizer_features_enable='10.2.0.1';
    Session altered.
    SQL> exec dbms_stats.gather_table_stats(user,'T1',method_opt=>'for all columns size 1');
    PL/SQL procedure successfully completed.
    SQL> select
    2 t1.small_vc
    3 from
    4 t1
    5 where
    6 t1.ind_pad = rpad('x',40)
    7 and t1.n1 = 0
    8 and t1.n2 = 4
    9 ;
    Execution Plan
    Plan hash value: 1429545322
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
    |
    0 SELECT STATEMENT 16 928 20 (0)00:00
    :01
    1 TABLE ACCESS BY INDEX ROWIDT1 16 928 20 (0)00:00
    :01
    * 2 INDEX RANGE SCAN T1_I1 16 4 (0)00:00
    :01
    Predicate Information (identified by operation id):
    2 - access("T1"."IND_PAD"='x' AND
    "T1"."N1"=0 AND "T1"."N2"=4)
    SQL> update t1 set n2=n1; //now t1 and t2 are correlated
    10000 rows updated.
    SQL> commit;
    Commit complete.
    SQL> exec dbms_stats.gather_table_stats(user,'T1',method_opt=>'for all columns size 1');
    PL/SQL procedure successfully completed.
    SQL> select
    2 t1.small_vc
    3 from
    4 t1
    5 where
    6 t1.ind_pad = rpad('x',40)
    7 and t1.n1 = 0
    8 and t1.n2 = 4
    9 ;
    Execution Plan
    Plan hash value: 3617692013
    Id Operation Name Rows Bytes Cost (%CPU)Time
    0 SELECT STATEMENT 16 928 84 (2)00:00:02 * 1 TABLE ACCESS FULLT1 16 928 84 (2)00:00:02
    Predicate Information (identified by operation id):
    1 - filter("T1"."N1"=0 AND "T1"."N2"=4 AND "T1"."IND_PAD"='x
    SQL> exec dbms_stats.delete_table_stats(user,'T1');
    //delete table stats test dynamic sampling
    PL/SQL procedure successfully completed.
    SQL> select
    2 t1.small_vc
    3 from
    4 t1
    5 where
    6 t1.ind_pad = rpad('x',40)
    7 and t1.n1 = 0
    8 and t1.n2 = 4
    9 ;
    Execution Plan
    Plan hash value: 1429545322
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
    |
    0 SELECT STATEMENT 1 60 1 (0)00:00
    :01
    1 TABLE ACCESS BY INDEX ROWIDT1 1 60 1 (0)00:00
    :01
    * 2 INDEX RANGE SCAN T1_I1 1 1 (0)00:00
    :01
    Predicate Information (identified by operation id):
    2 - access("T1"."IND_PAD"='x' AND
    "T1"."N1"=0 AND "T1"."N2"=4)
    Note
    - dynamic sampling used for this statement
    //under dynamic sampling ,oracle choose true explain plan
    SQL> exec dbms_stats.gather_table_stats(user,'T1',method_opt=>'for all columns size 1');
    PL/SQL procedure successfully completed.
    SQL> select /*+ index(t1) */
    2 t1.small_vc
    3 from
    4 t1
    5 where
    6 t1.ind_pad = rpad('x',40)
    7 and t1.n1 = 0
    8 and t1.n2 = 4
    9 ;
    Execution Plan
    Plan hash value: 1429545322
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
    |
    0 SELECT STATEMENT 16 928 256 (0)00:00
    :04
    1 TABLE ACCESS BY INDEX ROWIDT1 16 928 256 (0)00:00
    :04
    * 2 INDEX RANGE SCAN T1_I1 400 7 (0)00:00
    :01
    Predicate Information (identified by operation id):
    2 - access("T1"."IND_PAD"='x' AND
    "T1"."N1"=0 AND "T1"."N2"=4)
    SQL> set autot off
    SQL> select blevel,leaf_blocks,clustering_factor from user_indexes where table_name='T1';
    BLEVEL LEAF_BLOCKS CLUSTERING_FACTOR
    2 119 6201
    //index selectity and table selectity are 0.4
    index cost=2+119/25=7
    table cost=7+6201/25=256
    SQL> alter session set optimizer_features_enable='10.1.0.4';
    Session altered.
    SQL> set autot trace exp
    SQL> select /*+ index(t1) */
    2 t1.small_vc
    3 from
    4 t1
    5 where
    6 t1.ind_pad = rpad('x',40)
    7 and t1.n1 = 0
    8 and t1.n2 = 4
    9 ;
    Execution Plan
    Plan hash value: 1429545322
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
    |
    0 SELECT STATEMENT 16 928 13 (0)00:00
    :01
    1 TABLE ACCESS BY INDEX ROWIDT1 16 928 13 (0)00:00
    :01
    * 2 INDEX RANGE SCAN T1_I1 16 3 (0)00:00
    :01
    Predicate Information (identified by operation id):
    2 - access("T1"."IND_PAD"='x' AND
    "T1"."N1"=0 AND "T1"."N2"=4)
    //change optimizer to 10.1,then cbo caculate index selectity and table selectity 1/625

    >
    Very interesting again. I can reproduce your test case in 10.2.0.4, and it looks like you're right. I don't know whether it's intended behaviour or not, but in this particular case, when a index-only access is possible (and the table is not required) then the old selectivity formula is used (in this case 1/10000 * 1/10000), and it ignores the DISTINCT_KEYS of the index.
    The trace file shows that the index selectivity is actually determined as 1/10000 but it's obviously not used for the calculation.
    Interestingly, repeating the same test case in 11.1.0.7 shows that it uses the DISTINCT_KEYS again in the case you're using the entire index:
    Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production
    With the Partitioning, OLAP, Data Mining and Real Application Testing options
    Session altered.
    SQL>
    SQL> drop table m purge;
    Table dropped.
    SQL>
    SQL> create table m(id int,id1 int);
    Table created.
    SQL>
    SQL> insert into m select rownum,rownum+1 from dba_objects where rownum<10001;
    10000 rows created.
    SQL>
    SQL> insert into m select * from m;
    10000 rows created.
    SQL>
    SQL> insert into m select * from m;
    20000 rows created.
    SQL>
    SQL> insert into m select * from m;
    40000 rows created.
    SQL>
    SQL> insert into m select * from m;
    80000 rows created.
    SQL>
    SQL> commit;
    Commit complete.
    SQL>
    SQL> select count(*) from m;
      COUNT(*)
        160000
    SQL>
    SQL> create index i_m_1 on m(id,id1);
    Index created.
    SQL>
    SQL> exec dbms_stats.gather_table_stats(user,'M',method_opt=>'for all columns si
    ze 1', estimate_percent => null);
    PL/SQL procedure successfully completed.
    SQL>
    SQL> set autotrace traceonly
    SQL>
    SQL> select * from m where id=1;
    16 rows selected.
    Execution Plan
    Plan hash value: 3644412196
    | Id  | Operation        | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT |       |    16 |   112 |     2   (0)| 00:00:01 |
    |*  1 |  INDEX RANGE SCAN| I_M_1 |    16 |   112 |     2   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - access("ID"=1)
    Statistics
              1  recursive calls
              0  db block gets
              4  consistent gets
              0  physical reads
              0  redo size
            670  bytes sent via SQL*Net to client
            427  bytes received via SQL*Net from client
              3  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             16  rows processed
    SQL>
    SQL> select * from m where id=1 and id1=2;
    16 rows selected.
    Execution Plan
    Plan hash value: 3644412196
    | Id  | Operation        | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT |       |    16 |   112 |     1   (0)| 00:00:01 |
    |*  1 |  INDEX RANGE SCAN| I_M_1 |    16 |   112 |     1   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - access("ID"=1 AND "ID1"=2)
    Statistics
              1  recursive calls
              0  db block gets
              4  consistent gets
              0  physical reads
              0  redo size
            670  bytes sent via SQL*Net to client
            427  bytes received via SQL*Net from client
              3  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             16  rows processed
    SQL>
    SQL>So in 11.1.0.7 it seems to be consistent behaviour to take the DISTINCT_KEYS for an access using the entire index, but not in 10.2.
    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/

  • Optimizer=ALL_ROWS, PARTITION HASH, INDEX (RANGE SCAN) POOR PERFORMANCE?

    Our os is;
    SunOS 5.9
    and database is;
    Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - 64bit
    Our autotrace outputs are below also we have 10046 trace outputs;
    08:41:04 tcell_dev@SCME > set timing on
    08:41:19 tcell_dev@SCME > set autot on
    08:41:21 tcell_dev@SCME > SELECT lnpessv.PROFILE_ID FROM SCME.LNK_PROFILEENTITY_SUBSSERVVAR lnpessv
    08:41:25 2 WHERE lnpessv.SUBSCRIPTION_SERVICEVARIANT_ID = 1695083 ;
    PROFILE_ID
    1.400E+14
    1.600E+14
    Elapsed: 00:00:03.07
    Execution Plan
    0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=3 Card=3 Bytes=51)
    1 0 PARTITION HASH (ALL) (Cost=3 Card=3 Bytes=51)
    2 1 INDEX (RANGE SCAN) OF 'PK_PROFILEENTITY_SUBSSERVVAR' (INDEX (UNIQUE)) (Cost=
    3 Card=3 Bytes=51)
    Statistics
    1 recursive calls
    0 db block gets
    1539 consistent gets
    514 physical reads
    0 redo size
    258 bytes sent via SQL*Net to client
    273 bytes received via SQL*Net from client
    2 SQL*Net roundtrips to/from client
    0 sorts (memory)
    0 sorts (disk)
    2 rows processed
    08:41:32 tcell_dev@SCME > SELECT lnpessv.PROFILE_ID FROM SCME.LNK_PROFILEENTITY_SUBSSERVVAR lnpessv
    08:41:43 2 WHERE lnpessv.SUBSCRIPTION_SERVICEVARIANT_ID = 169508 ;
    PROFILE_ID
    1.400E+14
    1.600E+14
    Elapsed: 00:00:04.01
    Execution Plan
    0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=3 Card=3 Bytes=51)
    1 0 PARTITION HASH (ALL) (Cost=3 Card=3 Bytes=51)
    2 1 INDEX (RANGE SCAN) OF 'PK_PROFILEENTITY_SUBSSERVVAR' (INDEX (UNIQUE)) (Cost=
    3 Card=3 Bytes=51)
    Statistics
    1 recursive calls
    0 db block gets
    1537 consistent gets
    512 physical reads
    0 redo size
    258 bytes sent via SQL*Net to client
    273 bytes received via SQL*Net from client
    2 SQL*Net roundtrips to/from client
    0 sorts (memory)
    0 sorts (disk)
    2 rows processed
    Here we see 97% wait time, and responce time is unexceptable; These are the waits from 10046 trace file;
    WAIT #1: nam='gc cr grant 2-way' ela= 783 p1=341 p2=67065 p3=1 obj#=169530 tim=571610438395
    WAIT #1: nam='db file sequential read' ela= 6924 file#=341 block#=67065 blocks=1 obj#=169530 tim=571610445466
    WAIT #1: nam='gc cr grant 2-way' ela= 564 p1=294 p2=86263 p3=1 obj#=169531 tim=571610446493
    WAIT #1: nam='db file sequential read' ela= 6629 file#=294 block#=86263 blocks=1 obj#=169531 tim=571610453158
    INDEX RANGE SCAN PK_PROFILEENTITY_SUBSSERVVAR PARTITION: 1 512 (cr=1537 pr=512 pw=0 time=4272017 us)
    This is the related tables properties;
    OWNER     SCME
    TABLE_NAME     LNK_PROFILEENTITY_SUBSSERVVAR
    TABLESPACE_NAME     DATA01
    STATUS     VALID
    PCT_FREE     10
    INI_TRANS     10
    MAX_TRANS     255
    INITIAL_EXTENT     65536
    MIN_EXTENTS     1
    MAX_EXTENTS     2147483645
    LOGGING     NO
    BACKED_UP     N
    NUM_ROWS     239587420
    BLOCKS     1587288
    EMPTY_BLOCKS     0
    AVG_SPACE     0
    CHAIN_CNT     0
    AVG_ROW_LEN     41
    AVG_SPACE_FREELIST_BLOCKS     0
    NUM_FREELIST_BLOCKS     0
    DEGREE     1
    INSTANCES     1
    CACHE     N
    TABLE_LOCK     ENABLED
    SAMPLE_SIZE     71876226
    LAST_ANALYZED     29.05.2006 23:21:24
    PARTITIONED     NO
    TEMPORARY     N
    SECONDARY     N
    NESTED     NO
    BUFFER_POOL     DEFAULT
    ROW_MOVEMENT     DISABLED
    GLOBAL_STATS     YES
    USER_STATS     NO
    SKIP_CORRUPT     DISABLED
    MONITORING     YES
    DEPENDENCIES     DISABLED
    COMPRESSION     DISABLED
    DROPPED     NO
    We are suspecting rac configuration and hash partition and index usage with rac.
    Any comments will be welcomed,
    Thank you.
    Tonguç

    this is the output of dbms_metadata.get_ddl for the table;
    CREATE TABLE "SCME"."LNK_PROFILEENTITY_SUBSSERVVAR"
    (     "SUBSCRIPTION_SERVICEVARIANT_ID" NUMBER NOT NULL ENABLE NOVALIDATE,
         "PROFILE_ID" NUMBER NOT NULL ENABLE NOVALIDATE,
         "CREATED_BY_ID" NUMBER,
         "CREATED_DATE" DATE DEFAULT SYSDATE,
         "UPDATED_BY_ID" NUMBER,
         "UPDATED_DATE" DATE,
         CONSTRAINT "PK_PROFILEENTITY_SUBSSERVVAR" PRIMARY KEY ("SUBSCRIPTION_SERVICEVARIANT_ID", "PROFILE_ID")
    USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING
    STORAGE(INITIAL 4194304
    BUFFER_POOL DEFAULT)
    TABLESPACE "INDX02" GLOBAL PARTITION BY HASH ("SUBSCRIPTION_SERVICEVARIANT_ID","PROFILE_ID")
    (PARTITION "SYS_P52989"
    TABLESPACE "INDX02",
    PARTITION "SYS_P52990"
    TABLESPACE "INDX02",
    PARTITION "SYS_P54010"
    TABLESPACE "INDX02",
    PARTITION "SYS_P54011"
    TABLESPACE "INDX02",
    PARTITION "SYS_P54012"
    TABLESPACE "INDX02") ;
    CREATE UNIQUE INDEX "SCME"."PK_PROFILEENTITY_SUBSSERVVAR" ON "SCME"."LNK_PROFILEENTITY_SUBSSERVVAR" ("SUBSCRIPTION_SERVICEVARIANT_ID", "PROFILE_ID")
    PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING
    STORAGE(INITIAL 4194304
    BUFFER_POOL DEFAULT)
    TABLESPACE "INDX02" GLOBAL PARTITION BY HASH ("SUBSCRIPTION_SERVICEVARIANT_ID","PROFILE_ID")
    (PARTITION "SYS_P52989"
    TABLESPACE "INDX02",
    PARTITION "SYS_P52990"
    TABLESPACE "INDX02",
    PARTITION "SYS_P53499"
    TABLESPACE "INDX02",
    PARTITION "SYS_P53500"
    TABLESPACE "INDX02") ENABLE NOVALIDATE,
         CONSTRAINT "FK_LNK_PROF_REFERENCE_SDP_SUBS" FOREIGN KEY ("SUBSCRIPTION_SERVICEVARIANT_ID")
         REFERENCES "SCME"."SDP_SUBSCRIPTIONSERVICEVARIANT" ("SUBSCRIPTION_SERVICEVARIANT_ID") DEFERRABLE INITIALLY DEFERRED ENABLE NOVALIDATE
    ) PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 NOCOMPRESS NOLOGGING
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
    TABLESPACE "DATA01" ;
    CREATE INDEX "SCME"."LNK_PROFILEENTITY_SUB_HNDX3" ON "SCME"."LNK_PROFILEENTITY_SUBSSERVVAR" ("SUBSCRIPTION_SERVICEVARIANT_ID")
    PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING
    STORAGE(INITIAL 2097152
    BUFFER_POOL DEFAULT)
    TABLESPACE "INDX02" GLOBAL PARTITION BY HASH ("SUBSCRIPTION_SERVICEVARIANT_ID")
    (PARTITION "SYS_P53501"
    TABLESPACE "INDX02",
    PARTITION "SYS_P53502"
    TABLESPACE "INDX02",
    PARTITION "SYS_P53499"
    TABLESPACE "INDX02",
    PARTITION "SYS_P53500"
    TABLESPACE "INDX02") ;
    CREATE INDEX "SCME"."PROFILE_ID_NDX43" ON "SCME"."LNK_PROFILEENTITY_SUBSSERVVAR" ("PROFILE_ID")
    PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
    TABLESPACE "INDX03" ;
    ALTER TABLE "SCME"."LNK_PROFILEENTITY_SUBSSERVVAR" ADD CONSTRAINT "PK_PROFILEENTITY_SUBSSERVVAR" PRIMARY KEY ("SUBSCRIPTION_SERVICEVARIANT_ID", "PROFILE_ID")
    USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING
    STORAGE(INITIAL 4194304
    BUFFER_POOL DEFAULT)
    TABLESPACE "INDX02" GLOBAL PARTITION BY HASH ("SUBSCRIPTION_SERVICEVARIANT_ID","PROFILE_ID")
    (PARTITION "SYS_P52989"
    TABLESPACE "INDX02",
    PARTITION "SYS_P52990"
    PARTITION "SYS_P53498"
    TABLESPACE "INDX02",
    PARTITION "SYS_P53499"
    TABLESPACE "INDX02",
    PARTITION "SYS_P53500"
    TABLESPACE "INDX02") ENABLE NOVALIDATE;
    ALTER TABLE "SCME"."LNK_PROFILEENTITY_SUBSSERVVAR" MODIFY ("SUBSCRIPTION_SERVICEVARIANT_ID" NOT NULL ENABLE NOVALIDATE);
    ALTER TABLE "SCME"."LNK_PROFILEENTITY_SUBSSERVVAR" MODIFY ("PROFILE_ID" NOT NULL ENABLE NOVALIDATE);

  • Direct Path Reads instead of Sequential Reads for index range scan

    Database is 11.2. I have two development schemas, with the same table loaded in each schema - a 5 million row table. The execution path for the sql statement is the same against both tables; it's doing an index range scan.
    But it would appear Oracle performs a direct path read against one schema, and performs sequential reads against the other schema. I don't understand why I'm seeing different behavior when the execution plan is the same. Any ideas? These are two different schemas in the same database.

    There is not enough information.So you even these tables located same database and you gathered statistics it is not mean both run time wait event statistics must be same.Really they are different tables.If both query use INDEX RANGE SCAN the it is not mean these plans are same.What about table and their index statistics? are they same? for example num_row or num_blocks of both tables are same? also about indexes.In additionally if you want to get exact reason you can enable sql trace(using dbms_monitor or setting sql_trace parameter to true according session) and need analyze result trace file using tkprof utility.In additionally in 11g here when query execution time oracle automatically choose direct read path(serial) based on size of tables and size of buffer cache(also here is available some hidden parameter to controlling this behavior).

  • What is mean by index range scan and fast full scan

    What is mean by the following execution plans
    1)Table access by index rowid
    2) Index range scan
    3) Index fast full scan
    4) global index by rowid
    ..etc
    where i can get this information.In what situation CBO take these paths.Can you pls give me a link where i can find all these.I read these long time ago but not able to recollect
    Thanks
    Anand

    Oracle® Database Performance Tuning Guide
    10g Release 2 (10.2)
    Part Number B14211-01
    13.5 Understanding Access Paths for the Query Optimizer
    http://download-east.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#sthref1281

  • Taking more time in INDEX RANGE SCAN compare to the full table scan

    Hi all ,
    Below are the version og my database.
    SQL> select * from v$version;
    BANNER
    Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
    PL/SQL Release 10.2.0.4.0 - Production
    CORE 10.2.0.4.0 Production
    TNS for HPUX: Version 10.2.0.4.0 - Production
    NLSRTL Version 10.2.0.4.0 - Production
    I have gather the table statistics and plan change for sql statment.
    SELECT P1.COMPANY, P1.PAYGROUP, P1.PAY_END_DT, P1.PAYCHECK_OPTION,
    P1.OFF_CYCLE, P1.PAGE_NUM, P1.LINE_NUM, P1.SEPCHK  FROM  PS_PAY_CHECK P1
    WHERE P1.FORM_ID = :1 AND P1.PAYCHECK_NBR = :2 AND
    P1.CHECK_DT = :3 AND P1.PAYCHECK_OPTION <> 'R'
    Plan before the gather stats.
    Plan hash value: 3872726522
    | Id  | Operation         | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT  |              |       |       | *14306* (100)|          |
    |   1 |  *TABLE ACCESS FULL| PS_PAY_CHECK* |     1 |    51 | 14306   (4)| 00:02:52 |
    Plan after the gather stats:
    Operation     Object Name     Rows     Bytes     Cost
    SELECT STATEMENT Optimizer Mode=CHOOSE
              1           4
      *TABLE ACCESS BY INDEX ROWID     SYSADM.PS_PAY_CHECK*     1     51     *4*
        *INDEX RANGE SCAN     SYSADM.PS0PAY_CHECK*     1           3After gather stats paln look good . but when i am exeuting the query it take 5 hours. before the gather stats it finishing the within 2 hours. i do not want to restore my old statistics. below are the data for the tables.and when i am obserrving it lot of db files scatter rea
    NAME                                 TYPE        VALUE
    _optimizer_cost_based_transformation string      OFF
    filesystemio_options                 string      asynch
    object_cache_optimal_size            integer     102400
    optimizer_dynamic_sampling           integer     2
    optimizer_features_enable            string      10.2.0.4
    optimizer_index_caching              integer     0
    optimizer_index_cost_adj             integer     100
    optimizer_mode                       string      choose
    optimizer_secure_view_merging        boolean     TRUE
    plsql_optimize_level                 integer     2
    SQL> select count(*) from sysadm.ps_pay_check;
    select num_rows,blocks from dba_tables where table_name ='PS_PAY_CHECK';
      COUNT(*)
       1270052
    SQL> SQL> SQL>
      NUM_ROWS     BLOCKS
       1270047      63166
    Event                                 Waits    Time (s)   (ms)   Time Wait Class
    db file sequential read           1,584,677       6,375      4   36.6   User I/O
    db file scattered read            2,366,398       5,689      2   32.7   User I/Oplease let me know why it taking more time in INDEX RANGE SCAN compare to the full table scan?

    suresh.ratnaji wrote:
    NAME                                 TYPE        VALUE
    _optimizer_cost_based_transformation string      OFF
    filesystemio_options                 string      asynch
    object_cache_optimal_size            integer     102400
    optimizer_dynamic_sampling           integer     2
    optimizer_features_enable            string      10.2.0.4
    optimizer_index_caching              integer     0
    optimizer_index_cost_adj             integer     100
    optimizer_mode                       string      choose
    optimizer_secure_view_merging        boolean     TRUE
    plsql_optimize_level                 integer     2
    please let me know why it taking more time in INDEX RANGE SCAN compare to the full table scan?Suresh,
    Any particular reason why you have a non-default value for a hidden parameter, optimizercost_based_transformation ?
    On my 10.2.0.1 database, its default value is "linear". What happens when you reset the value of the hidden parameter to default?

  • Is index range scan the reason for query running long time

    I would like to know whether index range scan is the reason for the query running long time. Below is the explain plan. If so, how to optimise it? Please help
    Operation     Object     COST     CARDINALITY     BYTES
    SELECT STATEMENT ()          413     1000     265000
    COUNT (STOPKEY)                    
    FILTER ()                    
    TABLE ACCESS (BY INDEX ROWID)     ORDERS     413     58720     15560800
    INDEX (RANGE SCAN)     IDX_SERV_PROV_ID     13     411709     
    TABLE ACCESS (BY INDEX ROWID)     ADDRESSES     2     1     14
    INDEX (UNIQUE SCAN)     SYS_C004605     1     1     
    TABLE ACCESS (BY INDEX ROWID)     ADDRESSES     2     1     14
    INDEX (UNIQUE SCAN)     SYS_C004605     1     1     
    TABLE ACCESS (BY INDEX ROWID)     ADDRESSES     2     1     14
    INDEX (UNIQUE SCAN)     SYS_C004605     1     1

    The index range scan means that the optimiser has determined that it is better to read the index rather than perform a full table scan. So in answer to your question - quite possibly but the alternative might take even longer!
    The best thing to do is to review your query and check that you need every table included in the query and that you are accessing the tables via the best route. For example if you can access a table via primary key index that would be better than using a non-unique index. But the best way of reducing the time the query takes to run is to give it less tables (and indexes) to read.
    John Seaman
    http://www.asktheoracle.net

  • Index Range Scan / Deleted Leaf Blocks

    Hello guys,
    i have such a scenario on a big index / table which i can not reproduce on my test database, so i need to know how oracle handles the index range scan.
    For example:
    TABLE TAB with the following columns NR (number), I_DATE (date), TEXT (VARCHAR2(50))
    INDEX I_TAB on the column I_DATE.
    Now the index has blevel 2 and many leaf blocks. And now my question.
    Query: SQL> SELECT * from TAB WHERE I_DATE < 10.10.2004
    The index had stored some values which are a less than 2003 but these ones are already deleted (so the leaf blocks are gone to the freelist), but it was not reorganized.
    The execution plan is a INDEX RANGE SCAN on the INDEX I_TAB. Does the branch block still have pointers to the deleted leaf blocks which contained only 2003 values before (and so the INDEX RANGE SCAN scans all these blocks too) or are the pointers to these leaf blocks deleted in the branch block?
    Thanks and Regards
    Stefan

    You can verify it by yourself. See following:
    SELECT count(*) FROM index_test;
    ==> 1569408
    SELECT count(*) FROM index_test WHERE id <= 2;
    ==> 12
    -- Delete all except first 12 rows
    DELETE FROM index_test WHERE id > 2;
    -- Query and SQL Trace
    BEGIN
    FOR C IN (SELECT /*+index(index_test index_test_idx) deleted */ * FROM INDEX_TEST WHERE ID < 1000000) LOOP
    NULL;
    END LOOP;
    END;
    SELECT /*+index(index_test index_test_idx) deleted */ *
    FROM
    INDEX_TEST WHERE ID < 1000000
    call count cpu elapsed disk query current rows
    Parse 1 0.00 0.00 0 0 0 0
    Execute 1 0.00 0.00 0 0 0 0
    Fetch 1 0.00 0.00 0 3490 0 12
    total 3 0.00 0.01 0 3490 0 12
    ==> 3490 logical reads only for 12 rows and range scan??
    -- Index tree dump
    ALTER SESSION SET EVENTS 'IMMEDIATE TRACE NAME TREEDUMP LEVEL 67513'
    ----- begin tree dump
    branch: 0x1000124 16777508 (0: nrow: 6, level: 2)
    branch: 0x100b1ca 16822730 (-1: nrow: 557, level: 1)
    leaf: 0x1000125 16777509 (-1: nrow: 512 rrow: 12)
    leaf: 0x1000126 16777510 (0: nrow: 484 rrow: 0)
    leaf: 0x1000127 16777511 (1: nrow: 479 rrow: 0)
    leaf: 0x1000128 16777512 (2: nrow: 479 rrow: 0)
    leaf: 0x1000139 16777529 (3: nrow: 479 rrow: 0)
    leaf: 0x100013a 16777530 (4: nrow: 478 rrow: 0)
    branch: 0x100b401 16823297 (0: nrow: 558, level: 1)
    leaf: 0x100b1c9 16822729 (-1: nrow: 449 rrow: 0)
    leaf: 0x100b1cb 16822731 (0: nrow: 449 rrow: 0)
    leaf: 0x100b1cc 16822732 (1: nrow: 449 rrow: 0)
    ==> leaf:3488, branch: 7
    This means that almost all the branch and leaf nodes are read only for 12 keys.
    You can cross check this with the result of "10200" event which traces cr reads. You would find out that the blocks that are read by the query are exactly same as all the index blocks.
    This is what you mean? that the deleted leaf blocks(which contain no actual data) are read by range scan? Through the simple test, the anwer is "yes".

  • Determining indexes that are not used in 10g

    Is there a way to identify indexes that are not utilized in 10g? We have ADDM and AWR running nightly.
    Thanks in advance...

    You can enable index monitoring with
    alter index <index_name> monitoring usage;
    When the index is used V$OBJECT_USAGE.USED column will be set to YES. If the index is not used the USED column will show NO.
    test@ORCL> alter index i_test monitoring usage;
    Index altered.
    Elapsed: 00:00:00.04
    test@ORCL> select * from v$object_usage;
    INDEX_NAME                     TABLE_NAME                     MON USE START_MONITORING    END_MONITORING
    I_TEST                         TEST                           YES NO  01/04/2007 07:52:21
    Elapsed: 00:00:00.04
    test@ORCL> explain plan for
      2  select object_id from test;
    Explained.
    Elapsed: 00:00:00.10
    test@ORCL> select * from v$object_usage;
    INDEX_NAME                     TABLE_NAME                     MON USE START_MONITORING    END_MONITORING
    I_TEST                         TEST                           YES NO  01/04/2007 07:52:21
    Elapsed: 00:00:00.00
    test@ORCL> select count(*) from test;
      COUNT(*)
         50425
    Elapsed: 00:00:00.00
    test@ORCL> select * from v$object_usage;
    INDEX_NAME                     TABLE_NAME                     MON USE START_MONITORING    END_MONITORING
    I_TEST                         TEST                           YES NO  01/04/2007 07:52:21
    Elapsed: 00:00:00.00
    test@ORCL> select * from test where object_id =1;
    no rows selected
    Elapsed: 00:00:00.07
    test@ORCL> select * from v$object_usage;
    INDEX_NAME                     TABLE_NAME                     MON USE START_MONITORING    END_MONITORING
    I_TEST                         TEST                           YES YES 01/04/2007 07:52:21
    Elapsed: 00:00:00.00
    test@ORCL>You turn of index monitoring with the following:
    alter index <index_name> nomonitoring usage;

  • Query not using index when using 'or' clause

    I have a problem with something I can't understand about indexes in Oracle 11g.
    We can create test data with:
    create table test2(field1 varchar2(100),field2 varchar2(100),field3 number,field4 varchar2(100));
    create index test2_idx1 on test2(upper(field1));
    create index test2_idx1b on test2(field1);
    create index test2_idx2 on test2(field3);
    DECLARE
    j NUMBER :=1;
    BEGIN
    FOR i IN 1..500000
    LOOP
    INSERT
    INTO test2
    (field1,field2, field3, field4)
    VALUES
    ('field1='||i,'a', j, 'i' );
    IF (i mod 1000)=0 THEN
    j := j+1;
    END IF;
    END LOOP;
    COMMIT;
    END;
    EXEC DBMS_STATS.GATHER_TABLE_STATS ('system', 'test2');
    Then I make some explain plans which result I can't understand
    Query 1:
    SELECT * FROM test2 WHERE field3=1;
    Explain plan:
    Explain plan for query 01
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 1003 | 28084 | 10 (0)| 00:00:01 |
    | 1 | TABLE ACCESS BY INDEX ROWID| TEST2 | 1003 | 28084 | 10 (0)| 00:00:01 |
    |* 2 | INDEX RANGE SCAN | TEST2_IDX2 | 1003 | | 5 (0)| 00:00:01 |
    Everything OK here. Index is used.
    Query 2:
    SELECT * FROM test2 WHERE upper(field1)='FIELD1=1';
    Explain plan
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 1 | 28 | 4 (0)| 00:00:01 |
    | 1 | TABLE ACCESS BY INDEX ROWID| TEST2 | 1 | 28 | 4 (0)| 00:00:01 |
    |* 2 | INDEX RANGE SCAN | TEST2_IDX1 | 1 | | 3 (0)| 00:00:01 |
    Everything OK again. Index is used.
    Query 3:
    SELECT /*+ USE_CONCAT */ * FROM test2 WHERE field1='FIELD1=1' OR field3=1;
    Explain plan
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 1004 | 28112 | 14 (0)| 00:00:01 |
    | 1 | CONCATENATION | | | | | |
    | 2 | TABLE ACCESS BY INDEX ROWID| TEST2 | 1 | 28 | 4 (0)| 00:00:01 |
    |* 3 | INDEX RANGE SCAN | TEST2_IDX1B | 1 | | 3 (0)| 00:00:01 |
    |* 4 | TABLE ACCESS BY INDEX ROWID| TEST2 | 1003 | 28084 | 10 (0)| 00:00:01 |
    |* 5 | INDEX RANGE SCAN | TEST2_IDX2 | 1003 | | 5 (0)| 00:00:01 |
    Indenxes are used in concatenation. No problem again.
    Query 4:
    SELECT /*+ USE_CONCAT */ * FROM test2 WHERE upper(field1)='FIELD1=1' OR field3=1;
    Explain plan
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 1004 | 28112 | 641 (4)| 00:00:08 |
    | 1 | CONCATENATION | | | | | |
    |* 2 | TABLE ACCESS FULL | TEST2 | 1 | 28 | 631 (4)| 00:00:08 |
    |* 3 | TABLE ACCESS BY INDEX ROWID| TEST2 | 1003 | 28084 | 10 (0)| 00:00:01 |
    |* 4 | INDEX RANGE SCAN | TEST2_IDX2 | 1003 | | 5 (0)| 00:00:01 |
    Here my problem arises. Why is test2_idx1 not being used? Is it because it is a function index? Is there any workaround in this cases?
    Thanks a lot in advance.

    Interesting. A "workaround" which I thought first was:
    SELECT /*+ USE_CONCAT */ * FROM test2 WHERE upper(field1)='FIELD1=1'
    UNION ALL
    SELECT /*+ USE_CONCAT */ * FROM test2 WHERE field3=1;
    | Id  | Operation                    | Name       | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                                                                                                                                 
    |   0 | SELECT STATEMENT             |            |  1001 | 28042 |    15  (74)| 00:00:01 |                                                                                                                                                                                                                 
    |   1 |  UNION-ALL                   |            |       |       |            |          |                                                                                                                                                                                                                 
    |   2 |   TABLE ACCESS BY INDEX ROWID| TEST2      |     1 |    42 |     4   (0)| 00:00:01 |                                                                                                                                                                                                                 
    |*  3 |    INDEX RANGE SCAN          | TEST2_IDX1 |     1 |       |     3   (0)| 00:00:01 |                                                                                                                                                                                                                 
    |   4 |   TABLE ACCESS BY INDEX ROWID| TEST2      |  1000 | 28000 |    11   (0)| 00:00:01 |                                                                                                                                                                                                                 
    |*  5 |    INDEX RANGE SCAN          | TEST2_IDX2 |  1000 |       |     5   (0)| 00:00:01 |                                                                                                                                                                                                                 
    -------------------------------------------------------------------------------------------   But I do not like using UNION for such tricks. So I thought, what would ORACLE do without hint?
    SELECT  * FROM test2 WHERE upper(field1)='FIELD1=1' or field3=1;
    | Id  | Operation                        | Name       | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                                                                                                                             
    |   0 | SELECT STATEMENT                 |            |  1001 | 42042 |   176   (0)| 00:00:03 |                                                                                                                                                                                                             
    |   1 |  TABLE ACCESS BY INDEX ROWID     | TEST2      |  1001 | 42042 |   176   (0)| 00:00:03 |                                                                                                                                                                                                             
    |   2 |   BITMAP CONVERSION TO ROWIDS    |            |       |       |            |          |                                                                                                                                                                                                             
    |   3 |    BITMAP OR                     |            |       |       |            |          |                                                                                                                                                                                                             
    |   4 |     BITMAP CONVERSION FROM ROWIDS|            |       |       |            |          |                                                                                                                                                                                                             
    |*  5 |      INDEX RANGE SCAN            | TEST2_IDX2 |       |       |     5   (0)| 00:00:01 |                                                                                                                                                                                                             
    |   6 |     BITMAP CONVERSION FROM ROWIDS|            |       |       |            |          |                                                                                                                                                                                                             
    |*  7 |      INDEX RANGE SCAN            | TEST2_IDX1 |       |       |     3   (0)| 00:00:01 |                                                                                                                                                                                                             
    ----------------------------------------------------------------------------------------------- Thist looks perfect to me. (Please ignore the "higher" cost on the second plan. On your real data, it should be faster. Is it?)

  • Index not used on view when table stats exist

    Hello,
    I would be grateful if someone comes with ideas on the following problem I'm currently facing.
    I have a table with XMLTYPE data type column:
    sql-->desc ACFBNK_STMT008
    RECID     NOT NULL     VARCHAR2(200)
    XMLRECORD XMLTYPE
    I have a view V_ACFBNK_STMT008 on that table, in which the view columns are defined as extracted tags values from the XMLTYPE field, e.g. for the view field N_BOOKING_DATE:
    numcast(extractValue(xmlrecord,'/row/c25')) "N_BOOKING_DATE"
    (note: numcast is just a simple function that returns TO_NUMBER of its input argument)
    I have also a function-based index on this field of the table:
    CREATE INDEX train4.NIX_ACFBNK_STMT008_C25
    ON train4.ACFBNK_STMT008("TRAIN4"."NUMCAST"(extractValue(xmlrecord,'/row/c25')))
    And so, I'm executing on the view the following SQL statement:
    SELECT RECID FROM V_ACFBNK_STMT008 WHERE (N_BOOKING_DATE > TO_NUMBER('20070725'));
    Now, the problem comes: when statistics exist on the view base table (that is ACFBNK_STMT008) then the above statement is not using the index and is making a "table access full". When I delete the statistics for the table then the SQL runs fast with an "index range scan".
    Which is further strange - when I change the ">" operand with a "=" the SQL statement correctly captures the index regardless of whether or not statistics exist.
    I've tried to manually rewrite the SQL and include the "numcast" function in it:
    SELECT RECID FROM TRAIN4.V_ACFBNK_STMT008 WHERE ( N_BOOKING_DATE>train4.numcast(TO_NUMBER( '20010725' ) ));
    And in this way the index is used OK even with statistics existing!
    But regretfully I don't have a way to change the application and the SQL, so the only things I can change is the view and/or the index.
    Thank you in advance,
    Evgeni
    P.S.
    I've tried gathering statistics in both the following ways but still the problem persists:
    sql-->analyze table train4.ACFBNK_STMT008 compute statistics;
    sql-->exec dbms_stats.gather_table_stats(ownname=>'TRAIN4', tabname=>'ACFBNK_STMT008', CASCADE=>TRUE, partname=>NULL);

    Oh, and I forgot to mention: I cannot change the view definition as well (for example, to remove the "numcast"), since every now and then the application would recreate it automatically with the same code. :(

  • Due to Upper() query not using Indexes.......

    Hi,
    I have query as under:
    SELECT max(A.REGION_ID)
      FROM SOP_REGION_COUNTRY_MAP  A,
           SOP_REGION_PRODLINE_MAP B,
           SOP_REGION_ACTIVITY_MAP C
    WHERE A.REGION_ID = B.REGION_ID
       AND A.REGION_ID = C.REGION_ID
       AND upper(trim(COUNTRY_NAME)) = upper(trim(:Var3))
       AND upper(trim(STATE_NAME)) = upper(trim(:Var2))
       AND upper(trim(PRODLINE_NAME)) = upper(trim(:Var1))
       AND A.BATCH_JOB_IND = 1
       AND B.BATCH_JOB_IND = 1The plan of the above query is as under:
         SELECT STATEMENT, GOAL = CHOOSE                                   Cost=7     Cardinality=1     Bytes=73
    SORT AGGREGATE                                                       Cardinality=1     Bytes=73
      NESTED LOOPS                                                  Cost=7     Cardinality=1     Bytes=73
       HASH JOIN                                                  Cost=6     Cardinality=1     Bytes=68
        TABLE ACCESS FULL     Object owner=SOP     Object name=SOP_REGION_COUNTRY_MAP     Cost=3     Cardinality=1     Bytes=25
        TABLE ACCESS FULL     Object owner=SOP     Object name=SOP_REGION_PRODLINE_MAP     Cost=3     Cardinality=1     Bytes=43
       INDEX RANGE SCAN     Object owner=SOP     Object name=FK1_SOP_REGION_ACTIVITY_MAP     Cost=2     Cardinality=48     Bytes=240Now, this query does full table access of sop_region_country_map and sop_region_prodline_map even though it has index on country_name,state_name and prodline_name columns but as i have used Upper function the index is not used. Now, I need this upper function as business req. states that none of the comparison should be missed jsut because user has entered country,state and prodline in mixed cases...
    Can you pls let me know what to do if i want to avoid this FTA and instaed use indexes.. without sacrificing Upper() functionlaity..?
    Thx

    okay...its something like query rewrite grant for user...
    when i give that...i can create functional index now..
    but still i can use trunc() for functional index...it tells me that functional index can be created only for pure function...what is pure and impure function in oracle.

  • Oracle 10.2.0.4 Index on timestamp column not used when SYSTIMESTAMP Used.

    Hi,
    I have a table A with a column B timestamp(6). The tables contains around 300000 rows..
    I have created index 'idx' on the column B.
    When i compare column 'B' with systimestamp, it does not use the index, whereas if i compare 'B' with sysdate it uses the index.
    Eg :
    select count(*) from a where b<=sysdate;
    The above used the index 'idx' and executed in 1 second
    select count(*) from a where b<=systimestamp;
    The above does not use the index and executed in 19 seconds.
    Any Clue?
    Thanks in Advance

    Oracle is using Internal functions when you use SYSTIMESTAMP:
    Work around will be to use TO_TIMESTAMP as shown below.. Or define a function based index..
    You can check performance problem querying against a "TIMESTAMP WITH TIME ZONE" column link also
    SQL> create table a(b timestamp(6));
    Table created.
    SQL> insert into a
      2  select systimestamp+(level/24) from dual connect by level <= 30000;
    30000 rows created.
    SQL> commit;
    Commit complete.
    SQL> create index ndx on a(b);
    Index created.
    SQL> explain plan for
      2  select count(*) from a where b <= sysdate;
    Explained.
    SQL> select * from table(dbms_xplan.display);
    PLAN_TABLE_OUTPUT
    Plan hash value: 3858831102
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT  |      |     1 |    13 |     1   (0)| 00:00:01 |
    |   1 |  SORT AGGREGATE   |      |     1 |    13 |            |          |
    |*  2 |   INDEX RANGE SCAN| NDX  |     1 |    13 |     1   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       2 - access("B"<=SYSDATE@!)
    Note
       - dynamic sampling used for this statement
    18 rows selected.
    SQL> explain plan for
      2  select count(*) from a where b <= systimestamp;
    Explained.
    SQL>  select * from table(dbms_xplan.display);
    PLAN_TABLE_OUTPUT
    Plan hash value: 3918351354
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT   |      |     1 |    13 |    20  (15)| 00:00:01 |
    |   1 |  SORT AGGREGATE    |      |     1 |    13 |            |          |
    |*  2 |   TABLE ACCESS FULL| A    |     1 |    13 |    20  (15)| 00:00:01 |
    Predicate Information (identified by operation id):
       2 - filter(SYS_EXTRACT_UTC(INTERNAL_FUNCTION("B"))<=SYS_EXTRACT_UTC(S
                  YSTIMESTAMP(6)))
    Note
       - dynamic sampling used for this statement
    19 rows selected.
    --"Just tried using TO_TIMESTAMP"
    SQL> explain plan for
      2  select count(*) from a where b <= to_timestamp(systimestamp);
    Explained.
    SQL>
    SQL> select * from table(dbms_xplan.display);
    PLAN_TABLE_OUTPUT
    Plan hash value: 3858831102
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT  |      |     1 |    13 |     2   (0)| 00:00:01 |
    |   1 |  SORT AGGREGATE   |      |     1 |    13 |            |          |
    |*  2 |   INDEX RANGE SCAN| NDX  |     4 |    52 |     2   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       2 - access("B"<=TO_TIMESTAMP(TO_CHAR(SYSTIMESTAMP(6))))
    14 rows selected.Edited by: jeneesh on Oct 23, 2012 11:18 AM

  • Partition table not use index

    Hi Experts,
    Actually i have Production Partition table SMS_DELIVERY_NODETAILS its have partitions "PS_WD_01,PS_WD_02........... PS_WD_30". Partition base on date "TOOPERATOR" column like "10-11-2012 , 11-11-2012 ........".
    I have create local index "DELIVERY_CAMP" on "CAMPAIGN_NAME" column.
    I face issue in :
    case 1: Query using index "DELIVERY_CAMP" when i was use query with partition name "PS_WD_07"
    case 2: when query running with TOOPERATOR='2012-11-25' then table_sance_full.
    Oracle version =10g
    Os version = Linux 5.5
    SQL> DESC SMS_DELIVERY_NODETAILS
    Name                                                                                                              Null?    Type
    MSISDN                                                                                                                     VARCHAR2(15)
    TRANSACTIONID                                                                                                     NOT NULL VARCHAR2(50)
    TOOPERATOR                                                                                                                 VARCHAR2(25)
    FROMOPERATOR                                                                                                               VARCHAR2(25)
    STATUS                                                                                                                     VARCHAR2(25)
    TID_INDEX                                                                                                                  NUMBER
    CAMPAIGN_NAME                                                                                                              VARCHAR2(100)
    NETWORK_ERROR_CODE                                                                                                         VARCHAR2(20)
    Case 1:
    SQL> EXPLAIN PLAN FOR
      2  SELECT count(*) from SMS_DELIVERY_NODETAILS partition(PS_WD_07) where CAMPAIGN_NAME ='1353814653772_ftp_Churnscore100_pe_100';
    Explained.
    SQL> set line 200
    @?/rdbms/admin/utlxpls.sql
    SQL>
    PLAN_TABLE_OUTPUT
    Plan hash value: 2934568714
    | Id  | Operation               | Name          | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
    |   0 | SELECT STATEMENT        |               |     1 |    38 |    53   (0)| 00:00:01 |       |       |
    |   1 |  SORT AGGREGATE         |               |     1 |    38 |            |          |       |       |
    |   2 |   PARTITION RANGE SINGLE|               |  6320 |   234K|    53   (0)| 00:00:01 |    31 |    31 |
    |   3 |    PARTITION LIST ALL   |               |  6320 |   234K|    53   (0)| 00:00:01 |     1 |   100 |
    |*  4 |     INDEX RANGE SCAN    | DELIVERY_CAMP |  6320 |   234K|    53   (0)| 00:00:01 |  3001 |  3100 |
    PLAN_TABLE_OUTPUT
    Predicate Information (identified by operation id):
       4 - access("CAMPAIGN_NAME"='1353814653772_ftp_Churnscore100_pe_100')
    16 rows selected.
    case 2:
    SQL> SQL> EXPLAIN PLAN FOR
      2  SELECT count(*) from SMS_DELIVERY_NODETAILS WHERE TOOPERATOR='2012-11-25' and  CAMPAIGN_NAME ='1353814653772_ftp_Churnscore100_pe_100';
    Explained.
    SQL> @?/rdbms/admin/utlxpls.sql
    PLAN_TABLE_OUTPUT
    Plan hash value: 3258763602
    | Id  | Operation               | Name                   | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
    |   0 | SELECT STATEMENT        |                        |     1 |    58 | 76394   (2)| 00:15:17 |       |       |
    |   1 |  SORT AGGREGATE         |                        |     1 |    58 |            |          |       |       |
    |   2 |   PARTITION RANGE SINGLE|                        |     1 |    58 | 76394   (2)| 00:15:17 |    31 |    31 |
    |   3 |    PARTITION LIST ALL   |                        |     1 |    58 | 76394   (2)| 00:15:17 |     1 |   100 |
    |*  4 |     TABLE ACCESS FULL   | SMS_DELIVERY_NODETAILS |     1 |    58 | 76394   (2)| 00:15:17 |  3001 |  3100 |
    PLAN_TABLE_OUTPUT
    Predicate Information (identified by operation id):
       4 - filter("TOOPERATOR"='2012-11-25' AND "CAMPAIGN_NAME"='1353814653772_ftp_Churnscore100_pe_100')
    16 rows selected.

    Dear rp0428 ,
    1. the table and index DDL
    Table=>
    Table_name                     Partition_name                 Subpartition_name
    SMS_DELIVERY_NODETAILS         TOOPERATOR                     TID_INDEX
    Index=>
    create local index DELIVERY_TID_MSISDN_NODETAILS  on SMS_DELIVERY_NODETAILS(TRANSACTIONID,MSISDN);
    create local index DELIVERY_CAMP on SMS_DELIVERY_NODETAILS(CAMPAIGN_NAME);2. the query you used to collect the table and index stats
    SELECT count(*) from SMS_DELIVERY_NODETAILS WHERE TOOPERATOR='2012-11-25' and  CAMPAIGN_NAME ='1353814653772_ftp_Churnscore100_pe_100'; 3. the table, partition,subpartition row counts
    SQL> select PARTITION_POSITION,PARTITION_NAME,SUBPARTITION_COUNT,HIGH_VALUE from user_tab_partitions where TABLE_NAME='SMS_DELIVERY_NODETAILS' order by PARTITION_POSITION ;
    PARTITION_POSITION PARTITION_NAME                 SUBPARTITION_COUNT HIGH_VALUE
                     1 PS_WD_10                                      100 '2012-10-28'
                     2 PS_WD_11                                      100 '2012-10-29'
                     3 PS_WD_12                                      100 '2012-10-30'
                     4 PS_WD_13                                      100 '2012-10-31'
                     5 PS_WD_14                                      100 '2012-11-01'
                     6 PS_WD_15                                      100 '2012-11-02'
                     7 PS_WD_16                                      100 '2012-11-03'
                     8 PS_WD_17                                      100 '2012-11-04'
                     9 PS_WD_18                                      100 '2012-11-05'
                    10 PS_WD_19                                      100 '2012-11-06'
                    11 PS_WD_20                                      100 '2012-11-07'
    PARTITION_POSITION PARTITION_NAME                 SUBPARTITION_COUNT HIGH_VALUE
                    12 PS_WD_21                                      100 '2012-11-08'
                    13 PS_WD_22                                      100 '2012-11-09'
                    14 PS_WD_23                                      100 '2012-11-10'
                    15 PS_WD_24                                      100 '2012-11-11'
                    16 PS_WD_25                                      100 '2012-11-12'
                    17 PS_WD_26                                      100 '2012-11-13'
                    18 PS_WD_27                                      100 '2012-11-14'
                    19 PS_WD_28                                      100 '2012-11-15'
                    20 PS_WD_29                                      100 '2012-11-16'
                    21 PS_WD_30                                      100 '2012-11-17'
                    22 PS_WD_31                                      100 '2012-11-18'
    PARTITION_POSITION PARTITION_NAME                 SUBPARTITION_COUNT HIGH_VALUE
                    23 PS_WD_32                                      100 '2012-11-19'
                    24 PS_WD_01                                      100 '2012-11-20'
                    25 PS_WD_02                                      100 '2012-11-21'
                    26 PS_WD_03                                      100 '2012-11-22'
                    27 PS_WD_04                                      100 '2012-11-23'
                    28 PS_WD_05                                      100 '2012-11-24'
                    29 PS_WD_06                                      100 '2012-11-25'
                    30 PS_WD_07                                      100 '2012-11-26'
                    31 PS_WD_08                                      100 '2012-11-27'
                    32 PS_WD_09                                      100 '2012-11-28'
                    33 PS_WD_DEFAULT                                 100 MAXVALUE
    33 rows selected.

  • SQL Query not using Composite Index

    Hi,
    Please look at the below query:
    SELECT pde.participant_uid
    ,pde.award_code
    ,pde.award_type
    ,SUM(decode(pde.distribution_type
    ,'FORFEITURE'
    ,pde.forfeited_quantity *
    pde.sold_price * cc.rate
    ,pde.distributed_quantity *
    pde.sold_price * cc.rate)) AS gross_Amt_pref_Curr
    FROM part_distribution_exec pde
    ,currency_conversion cc
    ,currency off_curr
    WHERE pde.participant_uid = 4105
    AND off_curr.currency_iso_code =
    pde.offering_currency_iso_code
    AND cc.from_currency_uid = off_curr.currency_uid
    AND cc.to_currency_uid = 1
    AND cc.latest_flag = 'Y'
    GROUP BY pde.participant_uid
    ,pde.award_code
    ,pde.award_type
    In oracle 9i, i"ve executed this above query, it takes 6 seconds and the cost is 616, this is due to non usage of the composite index, Currency_conversion_idx(From_currency_uid, To_currency_uid, Latest_flag). I wonder why this index is not used while executing the above query. So, I've dropped the index and recreated it. Now, the query is using this index. After inserting many rows or say in 1 days time, if the same query is executed, again the query is not using the index. So everyday, the index should be dropped and recreated.
    I don't want this drop and recreation of index daily, I need a permanent solution for this.
    Can anyone tell me, Why this index goes stale after a period of time???? Please take some time and Solve this issue.
    -Sankar

    Hi David,
    This is Sankar here. Thankyou for your reply.
    I've got the plan table output for this problematic query, please go thro' it and help me out why the index CURRENCY_CONVERSION_IDX is used now and why it's not using while executing the query after a day or inserting some records...
    PLAN_TABLE_OUTPUT
    | Id | Operation | Name | Rows | Bytes | Cost |
    | 0 | SELECT STATEMENT | | 26 | 15678 | 147 |
    | 1 | TABLE ACCESS BY INDEX ROWID | PART_AWARD_PAYOUT_SCHEDULE | 1 | 89 | 2 |
    |* 2 | INDEX UNIQUE SCAN | PART_AWARD_PAYOUT_SCHEDULE_PK1 | 61097 | | 1 |
    | 3 | SORT AGGREGATE | | 1 | 67 | |
    |* 4 | FILTER | | | | |
    |* 5 | INDEX RANGE SCAN | PART_AWARD_PAYOUT_SCHEDULE_PK1 | 1 | 67 | 2 |
    | 6 | SORT AGGREGATE | | 1 | 94 | |
    |* 7 | FILTER | | | | |
    |* 8 | TABLE ACCESS BY INDEX ROWID | PART_AWARD_PAYOUT_SCHEDULE | 1 | 94 | 3 |
    |* 9 | INDEX RANGE SCAN | PART_AWARD_PAYOUT_SCHEDULE_PK1 | 1 | | 2 |
    |* 10 | FILTER | | | | |
    |* 11 | HASH JOIN | | 26 | 15678 | 95 |
    |* 12 | HASH JOIN OUTER | | 26 | 11596 | 91 |
    |* 13 | HASH JOIN | | 26 | 10218 | 86 |
    | 14 | VIEW | | 1 | 82 | 4 |
    | 15 | SORT GROUP BY | | 1 | 116 | 4 |
    |* 16 | TABLE ACCESS BY INDEX ROWID | PART_AWARD_LEDGER | 1 | 116 | 2 |
    |* 17 | INDEX RANGE SCAN | PARTICIPANT_UID_IDX | 1 | | 1 |
    |* 18 | HASH JOIN OUTER | | 26 | 8086 | 82 |
    |* 19 | HASH JOIN | | 26 | 6006 | 71 |
    | 20 | NESTED LOOPS | | 36 | 5904 | 66 |
    | 21 | NESTED LOOPS | | 1 | 115 | 65 |
    | 22 | TABLE ACCESS BY INDEX ROWID | CURRENCY_CONVERSION | 18 | 756 | 2 |
    |* 23 | INDEX RANGE SCAN | KLS_IDX_CURRENCY_CONV | 3 | | 1 |
    | 24 | VIEW | | 1 | 73 | 4 |
    | 25 | SORT GROUP BY | | 1 | 71 | 4 |
    | 26 | TABLE ACCESS BY INDEX ROWID| PART_AWARD_VALUE | 1 | 71 | 2 |
    |* 27 | INDEX RANGE SCAN | PAV_PARTICIPANT_UID_IDX | 1 | | 1 |
    | 28 | TABLE ACCESS BY INDEX ROWID | PARTICIPANT_AWARD | 199 | 9751 | 1 |
    |* 29 | INDEX UNIQUE SCAN | PARTICIPANT_AWARD_PK1 | 100 | | |
    |* 30 | INDEX FAST FULL SCAN | PARTICIPANT_AWARD_TYPE_PK1 | 147 | 9849 | 4 |
    | 31 | VIEW | | 1 | 80 | 10 |
    | 32 | SORT GROUP BY | | 1 | 198 | 10 |
    |* 33 | TABLE ACCESS BY INDEX ROWID | CURRENCY_CONVERSION | 1 | 42 | 2 |
    | 34 | NESTED LOOPS | | 1 | 198 | 8 |
    | 35 | NESTED LOOPS | | 2 | 312 | 4 |
    | 36 | TABLE ACCESS BY INDEX ROWID| PART_DISTRIBUTION_EXEC | 2 | 276 | 2 |
    |* 37 | INDEX RANGE SCAN | IND_PARTICIPANT_UID | 1 | | 1 |
    | 38 | TABLE ACCESS BY INDEX ROWID| CURRENCY | 1 | 18 | 1 |
    |* 39 | INDEX UNIQUE SCAN | CURRENCY_AK | 1 | | |
    |* 40 | INDEX RANGE SCAN | CURRENCY_CONVERSION_AK | 2 | | 1 |
    | 41 | VIEW | | 1 | 53 | 4 |
    | 42 | SORT GROUP BY | | 1 | 62 | 4 |
    |* 43 | TABLE ACCESS BY INDEX ROWID | PART_AWARD_VESTING | 1 | 62 | 2 |
    |* 44 | INDEX RANGE SCAN | PAVES_PARTICIPANT_UID_IDX | 1 | | 1 |
    | 45 | TABLE ACCESS FULL | AWARD | 1062 | 162K| 3 |
    | 46 | TABLE ACCESS BY INDEX ROWID | CURRENCY | 1 | 18 | 2 |
    |* 47 | INDEX UNIQUE SCAN | CURRENCY_AK | 102 | | 1 |
    Predicate Information (identified by operation id):
    2 - access("PAPS"."AWARD_CODE"=:B1 AND "PAPS"."PARTICIPANT_UID"=4105 AND "PAPS"."AWARD_TYPE"=:B2
    "PAPS"."INSTALLMENT_NUM"=1)
    4 - filter(4105=:B1)
    5 - access("PAPS"."AWARD_CODE"=:B1 AND "PAPS"."PARTICIPANT_UID"=4105 AND "PAPS"."AWARD_TYPE"=:B2)
    7 - filter(4105=:B1)
    8 - filter("PAPS"."STATUS"='OPEN')
    9 - access("PAPS"."AWARD_CODE"=:B1 AND "PAPS"."PARTICIPANT_UID"=4105 AND "PAPS"."AWARD_TYPE"=:B2)
    10 - filter("CC_A_P_CURR"."FROM_CURRENCY_UID"= (SELECT /*+ */ "CURRENCY"."CURRENCY_UID" FROM
    "EWAPDBO"."CURRENCY" "CURRENCY" WHERE "CURRENCY"."CURRENCY_ISO_CODE"=:B1))
    11 - access("SYS_ALIAS_7"."AWARD_CODE"="A"."AWARD_CODE")
    12 - access("SYS_ALIAS_7"."AWARD_CODE"="PVS"."AWARD_CODE"(+))
    13 - access("SYS_ALIAS_8"."AWARD_CODE"="PALS"."AWARD_CODE" AND
    "SYS_ALIAS_8"."AWARD_TYPE"="PALS"."AWARD_TYPE")
    16 - filter(TRUNC("PAL1"."LEDGER_ENTRY_DATE")<=TRUNC(SYSDATE@!) AND "PAL1"."ALLOC_TYPE"='IPU')
    17 - access("PAL1"."PARTICIPANT_UID"=4105)
    filter("PAL1"."PARTICIPANT_UID"=4105)
    18 - access("SYS_ALIAS_8"."AWARD_CODE"="PDES"."AWARD_CODE"(+) AND
    "SYS_ALIAS_8"."AWARD_TYPE"="PDES"."AWARD_TYPE"(+))
    19 - access("SYS_ALIAS_7"."AWARD_CODE"="SYS_ALIAS_8"."AWARD_CODE")
    23 - access("CC_A_P_CURR"."TO_CURRENCY_UID"=1 AND "CC_A_P_CURR"."LATEST_FLAG"='Y')
    27 - access("PAV"."PARTICIPANT_UID"=4105)
    filter("PAV"."PARTICIPANT_UID"=4105)
    29 - access("SYS_ALIAS_7"."AWARD_CODE"="SYS_ALIAS_9"."AWARD_CODE" AND
    "SYS_ALIAS_7"."PARTICIPANT_UID"=4105)
    30 - filter("SYS_ALIAS_8"."PARTICIPANT_UID"=4105)
    33 - filter("CC"."LATEST_FLAG"='Y')
    37 - access("PDE"."PARTICIPANT_UID"=4105)
    filter("PDE"."PARTICIPANT_UID"=4105)
    39 - access("OFF_CURR"."CURRENCY_ISO_CODE"="PDE"."OFFERING_CURRENCY_ISO_CODE")
    40 - access("CC"."FROM_CURRENCY_UID"="OFF_CURR"."CURRENCY_UID" AND "CC"."TO_CURRENCY_UID"=1)
    43 - filter("PV"."VESTING_DATE"<=SYSDATE@!)
    44 - access("PV"."PARTICIPANT_UID"=4105)
    filter("PV"."PARTICIPANT_UID"=4105)
    47 - access("CURRENCY"."CURRENCY_ISO_CODE"=:B1)
    Note: cpu costing is off
    93 rows selected.
    Please help me out...
    -Sankar

Maybe you are looking for