Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Michael.

Asked: August 12, 2001 - 11:01 pm UTC

Last updated: June 09, 2006 - 5:51 pm UTC

Version: 8.1.6.0

Viewed 1000+ times

You Asked

Hi Tom,

I would like to ask questions about indexes.

Suppose I have a table t1 which has columns a, b, c and d.
Columns a and b are the primary keys of t1, and hence a primary key index is built on them automatically.
If I qurey a sql likes "select a, d from t1 where b = ??", will the primary key index (a, b) be used in that case.

Also, I want to know that can an index on two or more columns(e.g. c, d) be used in the sql statement that containts part of the index in the where condition (e.g. "select a, b from t1 where c = ??")? Or do I need to build another index (i.e. on column c only) for that query?

Thanks for you help in advance
Michael

and Tom said...

for:

... If I qurey a sql likes "select a, d from t1 where b = ??", ....

the answer is probably not -- using a hint you might be able to force it to FULL SCAN the index to find the rows in the table but under normal circumstances -- it would not use that index.



For the second query you have -- we will most definitely make use of that index on (c,d) to answer queries against C by itself.



Rating

  (15 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Why indexed columns in primary key cannot be used seperately?

Michael, September 13, 2001 - 4:08 am UTC

Tom,

Why is it yes in the second query but not in the first query?

Is it not allowed to be used seperately in PK index?

Tom Kyte
September 13, 2001 - 11:29 am UTC

In the first query, the user wants to get columns A, D from T. there is an index on (a,b). The query is: select a,d from t where b = ?

In order to use the index in this case, we would have to inspect EVERY index entry (the index is sorted by A, not by B -- b=5 could be ANYWHERE in the index). Additionally -- since you want columns A, D as the output -- everytime we find an index entry where b=?, we would then have to do a table access by rowid to get the value for D.

It is most likely that rather then full scan the index and do single block IO to retrieve the row, we would opt to full scan the table instead. It is most LIKELY... It depends on the size, shape, volume and distribution of data.

It has nothing to do with the fact that it is a PK index, it is just an index where the columns are not in the optimal ordering to be used for a particular query.

For the second query -- the data in the index is sorted by C so a predicate like "c=?" can be used efficiently against that index using an index range scan.

Scanning composite index without predicate on index prefix column

Padders, September 13, 2001 - 11:54 am UTC

Tom,

I believe 9i has index skip scan algorithm for this situation and that it performs excellently. Can you point out any detailed documentation on skip scan?


Tom Kyte
September 13, 2001 - 12:55 pm UTC

See
</code> http://www.oracle.com/pls/db901/db901.to_toc?pathname=server.901/a87503/optimops.htm#51553 <code>

it works well if and only if the leading edge of the index (a in the example above) has very few discrete values and the optimizer understands that. For example and index on (GENDER,EMPNO) where gender has the values 'M', 'F' and EMPNO is unique. A query such as:

select * from t where empno = 5;

might consider (in 9i) using that index on t to satisfy the query in a "skip scan" method -- meaning the query will be processed conceptually like this:

select * from t where GENDER='M' and empno = 5
UNION ALL
select * from t where GENDER='F' and empno = 5;

In order to demonstrate this, I used the following script:

rop table t;

create table t
as
select decode(mod(rownum,2), 0, 'M', 'F' ) gender, all_objects.*
from all_objects
/
create index t_idx on t(gender,object_id)
/

analyze table t compute statistics
for table
for all indexes
for all indexed columns
/

alter session set sql_trace=true;
select * from t t1 where object_id = 55;
alter session set sql_trace=false;


drop table t;

create table t
as
select chr(mod(rownum,256)) gender, all_objects.*
from all_objects
/
create index t_idx on t(gender,object_id)
/

analyze table t compute statistics
for table
for all indexes
for all indexed columns
/

alter session set sql_trace=true;
select * from t t2 where object_id = 55;
alter session set sql_trace=false;

When the optimizer understands there are a few "sub indexes" by gender (as in the first case), it will use a skip scan:

select *
from
t t1 where object_id = 55


call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.01 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 7 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.00 0.01 0 7 0 1

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 23

Rows Row Source Operation
------- ---------------------------------------------------
1 TABLE ACCESS BY INDEX ROWID T
1 INDEX SKIP SCAN (object id 19845)


In the second case, there were 256 "sub indexes" and the optimizer properly adjusted its query plan:

select *
from
t t2 where object_id = 55


call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.01 0.01 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.04 0.03 1 266 9 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.05 0.04 1 266 9 1

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 23

Rows Row Source Operation
------- ---------------------------------------------------
1 TABLE ACCESS FULL T


As you can see -- in this case -- the skip scan did lots less work...

Thank You.

Christo Kutrovsky, June 14, 2003 - 4:33 pm UTC

Great example. Thanks you for showing it to us.


quick question on composite index

steve, February 08, 2004 - 7:23 pm UTC

Hi Tom,

you mentioned the index entries are sorted by the leading edge col in the index. In the case of a composite index, e.g. (a,b,c), are all the index entries are sorted by a first, then by b and last by c?
i.e.,
(a1,b1,c1)
(a1,b1,c2)
(a1,b1,c3)
(a1,b2,c1)
(a2,b1,c1)
(a2,b2,c1)
if ai<aj, i<j.

thanks!

Steve

Tom Kyte
February 08, 2004 - 9:10 pm UTC

yes, sort by a, inside of a by b, inside of b by c.

sweet!

James Blanding, February 10, 2004 - 1:30 pm UTC

The second reply was EXCEEDINGLY useful. Thanks! :)

Is skip scanning index an automatic feature or can be turned on and off? Thanks.

reader, February 19, 2004 - 6:48 pm UTC


Tom Kyte
February 19, 2004 - 7:34 pm UTC

it's an automatic feature -- if optimizer_features_enable is set to 9.x.x or above. (so yes, you can turn it off but you'll turn off lots of stuff)

Indexing on individual columns for fast retrieval

dharma, February 25, 2004 - 7:54 pm UTC

Thanks Tom the explanation was excellent.

We have a table with ~million rows and more to be added, and 80 columns. We show the table in forms 6 and the user can query on 20 columns. We have the primary key and a couple of indexes and the table is analyzed. But when queried on some columns (form the application in forms 6i) they tend to be very slow. our team suggests to create individual indexes on each on the 20 columns. Would fast full scan be involved in this or creating composite indexes help. We cannot restrict the User from querying on only certain columns as that feature is definitely needed.

Also data is loaded using sqlloader daily, very rare inserts, frequent updates possible and not OLTP.

As always your suggestion would be of great help.

Thanks,
-dharma
BTW Db is Oracle 9i rel 2

Tom Kyte
February 26, 2004 - 7:46 am UTC

hard to say with this limited information.

do they update the queried columns? or the other 60 columns?

Thanks!

dharma, February 27, 2004 - 4:01 pm UTC

Thanks for the immediate reply.

Not all of the 60 columns are updated. Only 10 to 20 of them would be updated, also there are updates on atleast 6-10 of the 20 queryable columns.

Also when querying, they can query by individual column, or multiple columns - there is no hard and fast rule there. Thats where I get stuck. :(

Would be glad to provide any other info.

Thanks Once again.
-dharma

Tom Kyte
February 27, 2004 - 4:35 pm UTC

sorry -- so bitmap indexes are out (if the 20 were not updated during the day, 20 bitmap indexes on the individual columns would be useful)


What about using TEXT? Index a function or set of columns on the table and use contains with section searching? a single index, all columns available in it.

Re. INDEX SKIP SCAN

Phil Stanworth, February 17, 2005 - 7:11 am UTC

Tom,

Thanks for a most useful explanation of 'skip scan'. It seems to me, though, that if an application invokes a lot of these, then the index definitions are probably not optimal. It must be more efficient to use an index which has the columns in an appropriate order, rather than to rely on the RDBMS interpolating a query into multiple UNIONed vesions of itself. Obviously this might mean having multiple indexes to cope with different queries, so there would be index update efficiencies to consider, but am I right that this is a general truth?

Regards
Phil

Tom Kyte
February 17, 2005 - 9:25 am UTC

or, the index is on (a,b)

and you query:

where a = :x and b = :y
where a = :x and b < :y
where a = :x and b > :y
where a = :x
where b = :y

and you wanted the least amount of indexes. I can do it with 1 if a is relatively "low cardinality"


meaning, my inserts/updates/deletes are much more efficient than yours (less indexes to maintain) and my selects are for the most part as optimal as yours.


if you are all about retrieval, and don't care about modification time, having two indexes would most likely be "optimal"

To skip scan or not to skip scan

Aru, April 19, 2005 - 6:19 pm UTC

Hi Tom,

Nice explainations above.

We have a query:-

select T4.dbid, (( (( (( (( (( RTRIM( TO_CHAR(T4.dbid) ))||(
((chr(9))||( to_char(T4.action_timestamp,'MON-DD-YYYY
HH24:MI'))))))||( ((chr(9))||( T4.user_name)))))||(
((chr(9))||( T4.action_name)))))||( ((chr(9))||(
T4.old_state)))))||( ((chr(9))||( T4.new_state)))),
T4.is_active, T4.expired_timestamp, T4.action_timestamp
from timespent T1,history T4
where T1.dbid = T4.entity_dbid
and 16781358 = T4.entitydef_id
and T1.dbid = 33556856 order by T4.action_timestamp;

The history table has 800000 rows, and no indexes so far created on it. What would be the optimum index strategy in this case here? Would creating a composite index on the enitty_dbid & entitydef_id be better or separate ones be better?

Thanks in advance,
Aru.

Tom Kyte
April 19, 2005 - 8:05 pm UTC

and how big is timespent and how many rows would the above return in general.


but what is the point of timespent in this query at all actually?

Skip scan or not to skip scan.

Aru, April 19, 2005 - 10:19 pm UTC

Hi Tom,

This query is generated from an out-of-the-box IBM application. Timespent is used to match the products that the company auctioned online and how long it took to sell it and then maintaines a history of them.
Details of the query run without indexes are:-

1051 rows selected.


Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2953 Card=4 Bytes=348)
1 0 SORT (ORDER BY) (Cost=2953 Card=4 Bytes=348)
2 1 NESTED LOOPS (Cost=2951 Card=4 Bytes=348)
3 2 INDEX (UNIQUE SCAN) OF 'TIMESPENT_PK' (UNIQUE) (Cost=1 Card=1 Bytes=6)
4 2 TABLE ACCESS (FULL) OF 'HISTORY' (Cost=2950 Card=4 Bytes=324)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
0 bytes sent via SQL*Net to client
0 bytes received via SQL*Net from client
0 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1051 rows processed

Thanks lots in advance,
Aru.
Btw- I'm using Oracle9iR2

Tom Kyte
April 20, 2005 - 6:46 am UTC

do not run things as SYS, ever. use SYS for admin, when you have to. PERIOD.

tkprof and autotrace are needed.

Index question

Aru, April 20, 2005 - 7:35 pm UTC

Hi Tom,

I did not use sys to run the query :-
Again

SQL> conn cq_prod/cq_prod@esgtd1;
Connected.
SQL> set autotrace traceonly statistics explain;
SQL> select T4.dbid,  (( (( (( (( (( RTRIM(  TO_CHAR(T4.dbid)))||(((chr(9))||( to_char(T4.action_timestamp,'MON-DD-YYYY HH24:MI'))))))||(  ((chr(9))||( T4.user_name)))))||(
((chr(9))||( T4.action_name)))))||(  ((chr(9))||( 
T4.old_state)))))||(  ((chr(9))||( T4.new_state)))), 
T4.is_active, T4.expired_timestamp, T4.action_timestamp 
from timespent T1,history T4 
where T1.dbid = T4.entity_dbid  
and 16781358 = T4.entitydef_id  
and  T1.dbid = 33556856 order by T4.action_timestamp;

1051 rows selected.


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2953 Card=4 Bytes=348)
   1    0   SORT (ORDER BY) (Cost=2953 Card=4 Bytes=348)
   2    1     NESTED LOOPS (Cost=2951 Card=4 Bytes=348)
   3    2       INDEX (UNIQUE SCAN) OF 'TIMESPENT_PK' (UNIQUE) (Cost=1 Card=1 Bytes=6)
   4    2       TABLE ACCESS (FULL) OF 'HISTORY' (Cost=2950 Card=4 Bytes=324)

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          0  consistent gets
          0  physical reads
          0  redo size
          0  bytes sent via SQL*Net to client
          0  bytes received via SQL*Net from client
          0  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       1051  rows processed

Tkprof:-


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       72      0.00       0.75      16676      19442          0        1051
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       74      0.00       0.75      16676      19442          0        1051

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 90  

Rows     Row Source Operation
-------  ---------------------------------------------------
   1051  SORT ORDER BY (cr=19442 r=16676 w=0 time=756121 us)
   1051   NESTED LOOPS  (cr=19442 r=16676 w=0 time=745667 us)
      1    INDEX UNIQUE SCAN TIMESPENT_PK (cr=2 r=0 w=0 time=16 us)(object id 40992)
   1051    TABLE ACCESS FULL HISTORY (cr=19440 r=16676 w=0 time=744357 us)

NOW i'm confused, why am I getting logical reads via autotrace=0?

Thanks,
Aru.



 

Tom Kyte
April 20, 2005 - 9:20 pm UTC

sorry -- something is wrong here

0 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
0 bytes sent via SQL*Net to client
0 bytes received via SQL*Net from client
0 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)

does not happen with you being "sys" in my experience.


stats look way out of date, autotrace and tkprof do not agree for those full scans at all.

confused - skip scan only working part of the time?

Elaine Hacklander, June 09, 2006 - 1:47 pm UTC

i just ordered your book, so hopefully that will cut down some of my confusion, but for now, please help.

in 9i you can use skip scan for indexes.  i understand that.  what i can't figure out is why the cost is higher for a skip scan.  and my other question is does skip scan only occur with equality comparisons or can it be configured somehow to work with "like"?

below was my test:

drop table tblone;
create table tblone(a number,b number,c varchar2(15)) tablespace di_small storage(initial 32k next 32k pctincrease 0);

SQL*Plus: Release 9.2.0.6.0 - Production on Fri Jun 9 13:32:26 2006

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Enter user-name:
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning option
JServer Release 9.2.0.6.0 - Production

SQL> SQL> SQL> SQL> SQL> SQL> SQL>
Table dropped.

SQL>
Table created.

SQL> Disconnected from Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning option
JServer Release 9.2.0.6.0 - Production

begin
for i in 1..1000
loop
insert into tblone values(i,i*2,'30022');
end loop;
end;
/


SQL*Plus: Release 9.2.0.6.0 - Production on Fri Jun 9 13:32:27 2006

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Enter user-name:
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning option
JServer Release 9.2.0.6.0 - Production

SQL> SQL> SQL> SQL> SQL> SQL> SQL> SQL>   2    3    4    5    6    7
PL/SQL procedure successfully completed.

SQL> SQL> Disconnected from Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning option
JServer Release 9.2.0.6.0 - Production
create index tblone_i on tblone(a,b,c);

SQL*Plus: Release 9.2.0.6.0 - Production on Fri Jun 9 13:32:27 2006

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Enter user-name:
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning option
JServer Release 9.2.0.6.0 - Production

SQL> SQL> SQL> SQL> SQL> SQL> SQL>
Index created.

SQL> Disconnected from Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning option
JServer Release 9.2.0.6.0 - Production
set echo on
set feedback on
set termout on
set time on
set timing on
alter session set nls_date_format='YYYY/MM/DD HH24:MI:SS';

select sysdate from dual;

exec dbms_stats.gather_table_stats(ownname=>'DI', -
tabname=>'TBLONE', -
estimate_percent=>'.5', -
method_opt=>'FOR COLUMNS A,B,C, SIZE 254', -
degree=>'9', -
cascade=>FALSE);
exec dbms_stats.gather_index_stats(ownname=>'DI', indname=>'TBLONE_I', degree=>'9');

alter session set nls_date_format='YYYY/MM/DD HH24:MI:SS';
select table_name,last_analyzed,num_buckets from user_tab_columns where table_name = 'TBLONE' and column_name = 'A';
select table_name,last_analyzed,num_buckets from user_tab_columns where table_name = 'TBLONE' and column_name = 'B';
select table_name,last_analyzed,num_buckets from user_tab_columns where table_name = 'TBLONE' and column_name = 'C';
set numwidth 20
select table_name,num_rows,avg_row_len from user_tables where table_name = 'TBLONE';


SQL*Plus: Release 9.2.0.6.0 - Production on Fri Jun 9 13:32:27 2006

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Enter user-name:
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning option
JServer Release 9.2.0.6.0 - Production

SQL> SQL> SQL> SQL> SQL> SQL> SQL> SQL> set echo on
SQL> set feedback on
SQL> set termout on
SQL> set time on
13:32:27 SQL> set timing on
13:32:27 SQL> alter session set nls_date_format='YYYY/MM/DD HH24:MI:SS';

Session altered.

Elapsed: 00:00:00.01
13:32:27 SQL>
13:32:27 SQL> select sysdate from dual;
2006/06/09 13:32:27

1 row selected.

Elapsed: 00:00:00.00
13:32:27 SQL>
13:32:27 SQL> exec dbms_stats.gather_table_stats(ownname=>'DI', -
13:32:27 > tabname=>'TBLONE', -
13:32:27 > estimate_percent=>'.5', -
13:32:27 > method_opt=>'FOR COLUMNS A,B,C, SIZE 254', -
13:32:27 > degree=>'9', -
13:32:27 > cascade=>FALSE);

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.29
13:32:27 SQL> exec dbms_stats.gather_index_stats(ownname=>'DI', indname=>'TBLONE_I', degree=>'9');

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.03
13:32:27 SQL>
13:32:27 SQL> alter session set nls_date_format='YYYY/MM/DD HH24:MI:SS';

Session altered.

Elapsed: 00:00:00.00
13:32:27 SQL> select table_name,last_analyzed,num_buckets from user_tab_columns where table_name = 'TBLONE' and column_name = 'A';
TBLONE                         2006/06/09 13:32:27          75

1 row selected.

Elapsed: 00:00:00.00
13:32:27 SQL> select table_name,last_analyzed,num_buckets from user_tab_columns where table_name = 'TBLONE' and column_name = 'B';
TBLONE                         2006/06/09 13:32:27          75

1 row selected.

Elapsed: 00:00:00.00
13:32:27 SQL> select table_name,last_analyzed,num_buckets from user_tab_columns where table_name = 'TBLONE' and column_name = 'C';
TBLONE                         2006/06/09 13:32:27           1

1 row selected.

Elapsed: 00:00:00.00
13:32:27 SQL> set numwidth 20
13:32:27 SQL> select table_name,num_rows,avg_row_len from user_tables where table_name = 'TBLONE';
TBLONE                                         1000                   13

1 row selected.

Elapsed: 00:00:00.01
13:32:27 SQL>
13:32:27 SQL> Disconnected from Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning option
JServer Release 9.2.0.6.0 - Production

SQL*Plus: Release 9.2.0.6.0 - Production on Fri Jun 9 13:32:28 2006

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Enter user-name:
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning option
JServer Release 9.2.0.6.0 - Production

SQL> SQL> SQL> SQL> SQL> SQL>   2
Explained.

SQL>
--------------------------------------------------------------------
| Id  | Operation            |  Name       | Rows  | Bytes | Cost  |
--------------------------------------------------------------------
|   0 | SELECT STATEMENT     |             |     1 |    13 |  1001 |
|*  1 |  INDEX SKIP SCAN     | TBLONE_I    |     1 |    13 |  1001 |
--------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("TBLONE"."A"=5 AND "TBLONE"."C"='30005')
       filter("TBLONE"."C"='30005')

Note: cpu costing is off

15 rows selected.

SQL> Disconnected from Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning option
JServer Release 9.2.0.6.0 - Production

SQL*Plus: Release 9.2.0.6.0 - Production on Fri Jun 9 13:32:38 2006

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Enter user-name:
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning option
JServer Release 9.2.0.6.0 - Production

SQL> SQL> SQL> SQL> SQL> SQL>   2
Explained.

SQL>
--------------------------------------------------------------------
| Id  | Operation            |  Name       | Rows  | Bytes | Cost  |
--------------------------------------------------------------------
|   0 | SELECT STATEMENT     |             |     1 |    13 |     2 |
|*  1 |  INDEX RANGE SCAN    | TBLONE_I    |     1 |    13 |     2 |
--------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("TBLONE"."A"=5 AND "TBLONE"."C" LIKE '30005%')
       filter("TBLONE"."C" LIKE '30005%')

Note: cpu costing is off

15 rows selected.

maybe this isn't a valid test?  maybe i misunderstood something?  i would be grateful for any enlightenment that you could provide. 

Tom Kyte
June 09, 2006 - 2:08 pm UTC

unfortunately, we cannot see your queries so after all of that, we cannot really see anything.

why don't you have a single (CONCISE, SMALL IS GOOD) script that you spool and cut and paste it inline like all of the other examples here..

sorry...internal shell stuff. here are the queries.

Elaine Hacklander, June 09, 2006 - 3:43 pm UTC

same table as above.  

the first query was:
SQL> Select /*+ index_ss(TBLONE TBLONE_I) */ * from TBLONE where a=5 and c = '30005';

the second query was:
SQL> set autotrace traceonly;
SQL> Select /*+ index_ss(TBLONE TBLONE_I) */ * from TBLONE where a=5 and c like '30005';


now i am really confused.  the first several time we ran this explain plan, the first query utilized the skip scan, but the second query did not, hence my question to you in the first place.  now i am getting the following:

SQL> set autotrace traceonly;
SQL> Select /*+ index_ss(TBLONE TBLONE_I) */ * from TBLONE where a=5 and c like '30005';

no rows selected


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1001 Card=1 Bytes=13
          )

   1    0   INDEX (SKIP SCAN) OF 'TBLONE_I' (NON-UNIQUE) (Cost=1001 Ca
          rd=1 Bytes=13)





Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads
          0  redo size
        383  bytes sent via SQL*Net to client
        456  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed

any ideas on what we did to facilitate oracle using the skip scan?   

Tom Kyte
June 09, 2006 - 5:51 pm UTC

*need* full blow example, in a conscise format. without extra stuff.

just the creates, gathers, queries - all together.

having a moment

Elaine H, June 09, 2006 - 4:45 pm UTC

Sorry Tom.  the original query was thus with the following explain plan.  i forgot the % in the one i posted earlier.

SQL> Select /*+ index_ss(TBLONE TBLONE_I) */ * from TBLONE where a=5 and c like '30005%'
  2  /

no rows selected


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=13)
   1    0   INDEX (RANGE SCAN) OF 'TBLONE_I' (NON-UNIQUE) (Cost=2 Card
          =1 Bytes=13)





Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads
          0  redo size
        383  bytes sent via SQL*Net to client
        456  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed

sorry for any inconvenience, your help is greatly appreciated.