Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
![]() |
![]() |
Home -> Community -> Usenet -> c.d.o.server -> Re: Oracle and JDBC Timestamp Types Confusion
fitzjarrell_at_cox.net wrote:
> Robert Klemme wrote: >
> > > Your primary key uses a concatenated index, making none of the > individual columns unique; only the combination of the respective > values produces a unique key. As such, there is no 'range' to scan > with this index, as the same timestampid could occur anywhere in the > data. Were timestampid your only column in the primary key an INDEX > RANGE SCAN would be performed. As you have it configured timestampid > is not unique, thus the INDEX FULL SCAN is necessary to find any and > all records meeting your criteria. > > > David Fitzjarrell >
Timestampid is the leading column, so an INDEX RANGE SCAN seems a possible path. I'd rather assume that missing/outdated statistics or the optimizer asuming a wrong value for the bind variable are leading to the full scan.
Consider the following (on 10g):
SQL> create table test (timestampid date not null, owner varchar2(32) not null, object_name varchar2(30));
Table created.
SQL> create index idx_test on test (timestampid, owner);
Index created.
SQL> alter table test add constraint pk_test primary key (timestampid, owner);
Table altered.
SQL> insert into test select sysdate -(10000 - rownum) as timestampid, owner, object_name from all_objects where rownum < 10000;
9999 rows created.
SQL> commit;
Commit complete.
SQL> exec dbms_stats.gather_table_stats (user, 'TEST', cascade=> true);
PL/SQL procedure successfully completed.
SQL> variable dateid varchar2(11)
SQL> exec :dateid := '21-JAN-2005';
PL/SQL procedure successfully completed.
SQL> explain plan for select * from test where timestampid < to_date (:dateid, 'DD-MON-YYYY');
Explained.
SQL> select * from table (dbms_xplan.display);
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 500 | 18500 | 4 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST | 500 | 18500 | 4 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | IDX_TEST | 90 | | 2 (0)| 00:00:01 | ----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
2 - access("TIMESTAMPID"<TO_DATE(:DATEID,'DD-MON-YYYY'))
filter("TIMESTAMPID"<TO_DATE(:DATEID,'DD-MON-YYYY'))
15 rows selected.
SQL> select count (*) from test where timestampid < to_date (:dateid, 'DD-MON-YYYY');
COUNT(*)
9796
SQL> SQL> So the INDEX RANGE SCAN is a possible path, your post sounded like it wasn't (and note how the CBO wrongly guessed the outcome of to_date). Unfortunately SQL*Plus doesn't have support a date type, so I can't make the demonstration more similar to the OPs situation.
Regards,
Holger
Received on Fri Aug 12 2005 - 03:17:31 CDT
![]() |
![]() |