Skip to Main Content
  • Questions
  • full table scan & unique-nonunique indexes

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Rakesh.

Asked: November 03, 2003 - 8:12 am UTC

Last updated: November 28, 2006 - 7:57 pm UTC

Version: 817

Viewed 1000+ times

You Asked

Hi Tom

1) Pardon me if this question sounds repetitive to you.
I was going through the forums the thread on index scan & full table scan where
you mention that not to consider full table scan as evils

Till now i was under the impression that index scan will always result in faster access
than full table scans
Could you site some scenarios where full table scans are better over index scans




2) Whats the difference between a unique & non unique index & which are more advantageous to use in which situations

Regards
Rakesh



and Tom said...

1) </code> http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:6749454952894#6760861174154 <code>

2) well, there are times you cannot use a unique index -- when the data is not unique. so that is pretty clear cut.

I never create unique indexes -- i create constraints that may create a unique index. I create "non unique" indexes to tune with -- but if I was to create a unique index -- that really means I meant to create a UNIQUE CONSTRAINT! That gives the opimizer more information, more sematics.


so, never create a unique index, use "non unique" indexes to tune, use constraints to get others created as a side effect.



Rating

  (7 ratings)

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

Comments

A reader, November 04, 2003 - 10:17 am UTC


Also valid for partitioned indexes?

Eric, November 04, 2003 - 10:48 am UTC

Hi Tom,
I'm wonder if your comment for the second question is also valid for local nonprefixed indexes.
I thought the only way to have a unique index on those are the global unique indexes.
Also, Oracle automatically creates a global unique index if you specify a unique constraint on a non partition key column. Is there a way to avoid that behavior? i.e. having a local (nonprefixed) index enforced with a unique constraint?
Thanks.

Tom Kyte
November 04, 2003 - 4:04 pm UTC

yes, for partitioned.

unique indexes should be created by UNIQUE or PRIMARY KEY constraints -- for if you have a unique index without one or the other, you've done something wrong.


you can use the "using index" clause of the constraint clause to get the global partitioning scheme you desire (else you get a single partition)

if the unique columns are NOT part of the partition key, you'll be using a GLOBAL index to enforce uniqueness.

Question.

Christo Kutrovsky, November 05, 2003 - 2:54 pm UTC

Can you confirm, that the optimiser will NOT consider the fact that a given index is unique, if there's no unique constraint associated with it ?

If yes, can you confirm with a test case on a 9iR2 daatabase.


Tom Kyte
November 06, 2003 - 7:10 am UTC

nope, never said that. it is not that it will not consider it (it'll cost certain things differently) it is that query rewrite relies on constraints being in place -- not indexes. so it can affect the optimizer, but the optimizer doesn't "not" consider it.

Cool.

Christo Kutrovsky, November 06, 2003 - 10:36 am UTC

Got it.

I guess I did not express my self correctly, by "not" consider it I ment will treat it differently (i.e. could result in a different plan) if only a unique index was present, and not a unique constraint.

I guess it the most affected are query rewrites.



Great but...

NOTNA, October 18, 2005 - 9:39 am UTC

when you say:

"so, never create a unique index, use "non unique" indexes to tune"

I am just curious why oracle introduced a syntax to create a unique index even if non unique index will be faster. Also, when oracle shows a plan, it uses the index right? so if I have a non unique index it will always perform a range scan instead of unique scan, is that correct? Oracle never use the constraint to access the data. Thank you very much for the clarification as usual.

Cheers,
NOTNA

Tom Kyte
October 18, 2005 - 9:48 am UTC

I should never say never...

using function based indexes - using a unique index can definitely make sense (complex integrity constraints)......

in general - if something is unique, use a UNIQUE constraint or PRIMARY KEY constraint. that is used by the optimizer, it understands.

On indexes

Apurva, November 27, 2006 - 2:45 pm UTC

Two short questions on indexes (for which I scoured the Net without an answer):

1. Which index - Unique B*Tree or Non-Unique B*Tree - will give a better query performance and why (what's the underlying logic)?

2. I have a table, say T, which has two columns - COL_A and COL_B

Now, consider two scenarios:

Scenario A:
* I build B*Tree index (doesn't matter whether it's Unique or not) on COL_A
* I add PK constraint on COL_A
* I've never been happier in life

Scenario B:
* I build BITMAP index (again, doesn't matter whether it's Unique or not) on COL_A
* I add PK constraint on COL_A
* Oracle doesn't like it -- it says: the column is already indexed

Clearly, Oracle needs an underlying B*Tree index to implement PK constraint logic. My question is: Is there a good enough reason for this differential treatment?
Why can't Oracle use an undelying BITMAP index to implement PK constraint?


P.S.: I am new to Oracle, so if these questions are too simplistic then please refrain from answering.

Regards

Tom Kyte
November 27, 2006 - 7:58 pm UTC

1) neither really. The presumption would be "the indexed column is in fact unique" so one row comes back - both indexes would be pretty close - the unique index might be marginally better since we know "unique scan". In general, if you have a unique column, you will use a unique constraint - and by default we'll create the unique index for you (assuming the column is not indexed). If you ask for a DEFERRABLE unique constraint, we'll create a non-unique index for you.

/*
drop table t;

create table t ( x int, y int );
insert into t select rownum, rownum from all_objects;
create unique index t_idx_x on t(x);
create index t_idx_y on t(y);
alter table t add constraint x_unique unique(x);
alter table t add constraint y_unique unique(y);

*/
column cnt new_val cnt
select count(*) cnt from t;
@trace
begin
for i in 1 .. &cnt
loop
for x in ( select * from t where x = i )
loop
null;
end loop;
for x in ( select * from t where y = i )
loop
null;
end loop;
end loop;
end;
/


SELECT * FROM T WHERE X = :B1

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 50175 6.54 6.26 0 0 0 0
Fetch 50175 1.44 1.28 0 150525 0 50175
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 100351 7.98 7.55 0 150525 0 50175
********************************************************************************
SELECT * FROM T WHERE Y = :B1

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 50175 6.59 6.28 0 0 0 0
Fetch 50175 1.71 1.61 0 150635 0 50175
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 100351 8.30 7.90 0 150635 0 50175


2) because it cannot (implementation of Oracle says "no"), it will not, it doesn't AND if the column were unique, well - would you care to comment on the sensibility of using a bitmap index on it??? :)

think about it - a bitmap index on a unique column, under what circumstances would that be a "good idea"?



ThanksTom

Apurva, November 28, 2006 - 2:56 pm UTC

Tom,

Can you change AskTom to ThanksTom :)

Coming back to -

'would you care to comment on the
sensibility of using a bitmap index on it?'

...I asked that from a purely technical perspective. I understand that a Unique column will have degree of cardinality ~100, which doesn't make it a good candidate for BIMAP index -- B*Tree search on this column will be of O(log n) whereas BIMAP search will be of O(n).

Regards.




Tom Kyte
November 28, 2006 - 7:57 pm UTC

b*tree's are not like that at all.

most b*trees - even on millions of rows - take 3 or 4 searches to find the answer.

it is all about the height of the index.

same with the bitmap!!! (bitmaps are just a data structure stored in a b*tree index...)