Skip to Main Content
  • Questions
  • Difference between constraints and Indexes

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Anthony.

Asked: March 13, 2002 - 9:17 pm UTC

Last updated: September 05, 2017 - 11:50 am UTC

Version: 8.1.6

Viewed 50K+ times! This question is

You Asked

Hi Tom,

First of all I personally thank you (and of course I believe that others do) for all the support you have given to us in giving us this opportunity to post questions thru this site.


Now with my concern:

1. I understand that constraints enforces business rule in my database and indexes gives our queries makes much faster if we create and index to a table.

My question is, what is the relationship between this 2.
For example :

SQL> create table online_tb (seq_no number, trun_num number, head varchar2(20) constraint NN NOT NULL, tran_Date date);

then,
alter table online_tb add constraint ol_tb_uk1
unique (seq_no,trun_num, head);

SQL> select uniqueness,index_name from user_indexes where table_name='ONLINE_TB';

UNIQUENES INDEX_NAME
--------- ------------------------------
UNIQUE OL_TB_UK1

SQL> SELECT CONSTRAINT_NAME, TABLE_NAME FROM USER_CONSTRAINTS WHERE TABLE_NAME='ONLINE_TB';

CONSTRAINT_NAME TABLE_NAME
------------------------------ ------------------------------
NN ONLINE_TB
OL_TB_UK1 ONLINE_TB

SQL> ALTER TABLE ONLINE_tB ADD CONSTRAINT OL_TB_PK1 PRIMARY KEY (SEQ_NO,TRUN_NUM,HEAD);
ALTER TABLE ONLINE_tB ADD CONSTRAINT OL_TB_PK1 PRIMARY KEY (SEQ_NO,TRUN_NUM,HEAD)
*
ERROR at line 1:
ORA-02261: such unique or primary key already exists in the table


SQL> CREATE UNIQUE INDEX OL_TB_UNIQ ON ONLINE_TB (SEQ_NO,TRUN_NUM,HEAD);
CREATE UNIQUE INDEX OL_TB_UNIQ ON ONLINE_TB (SEQ_NO,TRUN_NUM,HEAD)
*
ERROR at line 1:
ORA-01408: such column list already indexed

And if I create a UNIQUE INDEX on that same columns it gives me an error, Can you explain to me y?


2. We are receiving an error :
'ASSERTION FAILED'
PROGRAM : C:\ORANT\BIN\ifrun60.exe
FILE : e:\f994w32\src\if\iff\ifrlf.c
LINE : 890

Thank you very much and more power.




and Tom said...

Well, indexes may (or may NOT) make your queries go faster -- it depends.

The relationship between indexes and constraints is:

o a constraint MIGHT create an index or use an existing index to efficient enforce itself. For example, a PRIMARY KEY constraint will either create an index (unique or non-unique depending) or it will find an existing suitable index and use it.

o an index has nothing to do with a constraint. An index is an index.


So, a constraint MIGHT create/use and index. An INDEX is an INDEX, nothing more, nothing less.


2) please contact support, they'll be able to help you.

Rating

  (16 ratings)

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

Comments

PK with non -unique index ??

A reader, March 14, 2002 - 9:00 am UTC

Regarding your statement "a PRIMARY KEY constraint will either create an
index (unique or non-unique depending) "
Here's my dumb question.
Please correct me if I am wrong a primary key will always
(use or) create a unique Index and never a non unique one.
SO why the statement :either create an
index (unique or non-unique depending).
Can u please give an example of PK using/creating non unique index
Thanx

Tom Kyte
March 14, 2002 - 10:10 am UTC

Constraints and Indexes

Martin, April 22, 2002 - 10:07 am UTC

Hi Tom,

Firstly, thanks for a brilliant site, the depth of knowledge and help is priceless. Just a quick question :

You said

"

The relationship between indexes and constraints is:

o a constraint MIGHT create an index or use an existing index to efficient 
enforce itself.  For example, a PRIMARY KEY constraint will either create an 
index (unique or non-unique depending) or it will find an existing suitable 
index and use it.

o an index has nothing to do with a constraint.  An index is an index.


So, a constraint MIGHT create/use and index.  An INDEX is  an INDEX, nothing 
more, nothing less.
"

But consider the following SQL :

SQL> create table test_table ( A  VARCHAR2(10) );

Table created.

SQL> create unique index A_UI on test_table(a);

Index created.

SQL> select constraint_name, constraint_type
  2  from user_constraints
  3  where table_name = 'TEST_TABLE';
  
no rows selected

SQL> INSERT INTO TEST_TABLE VALUES ('A');

1 row created.

SQL> /
INSERT INTO TEST_TABLE VALUES ('A')
*
ERROR at line 1:
ORA-00001: unique constraint (BMTEST.A_UI) violated

Is this just a bit of a herring rouge error or is this a little example of how an index ISN'T just an index, but also a constraint (whether an "internal" constraint or otherwise)?
 

Tom Kyte
April 22, 2002 - 10:36 am UTC

It isn't a constraint.  the error message "misnames" it.  


If it were a constraint, you could create a foreign key to it -- but you cannot.


ops$tkyte@ORA817DEV.US.ORACLE.COM> create table test_table ( A  VARCHAR2(10), b varchar2(10) );

Table created.

ops$tkyte@ORA817DEV.US.ORACLE.COM> 
ops$tkyte@ORA817DEV.US.ORACLE.COM> create unique index A_UI on test_table(a)
  2  
ops$tkyte@ORA817DEV.US.ORACLE.COM> alter table test_table add constraint fk foreign key(b) references test_table(a);
alter table test_table add constraint fk foreign key(b) references test_table(a)
                                                                              *
ERROR at line 1:
ORA-02270: no matching unique or primary key for this column-list


ops$tkyte@ORA817DEV.US.ORACLE.COM> 
ops$tkyte@ORA817DEV.US.ORACLE.COM> alter table test_table add constraint pk primary key(a);

Table altered.

ops$tkyte@ORA817DEV.US.ORACLE.COM> alter table test_table add constraint fk foreign key(b) references test_table(a);

Table altered.



 

mike, July 25, 2002 - 5:14 am UTC

I don't understand. If unique index can improve performance(sometimes) and enforce uniqueness, why do we need primary key constraint?

Tom Kyte
July 25, 2002 - 6:53 am UTC

A primary key MEANS SOMETHING. It conveys a specific semantic meaning.

A unique index, does not.

A primary key may or may not use a unique index. A primary key also infers (and enforces) NOT NULL.


the underlying tools (index -- unique or not, plus NOT NULL constraint) are used to build a primary key. A primary key means, semantically more then a unique index does.

Consider it "documentation"

Unique Index, Unique Constraint

Inga, July 25, 2002 - 7:41 am UTC

Hello Tom!
What is the better to use to enforce uniqueness - unique index or unique constraint?

Tom Kyte
July 25, 2002 - 10:23 pm UTC

unique constraint.

it has more semantic meaning
it can be deferrable if you want
it is better then a unique index

PK

Reader, August 16, 2002 - 10:35 am UTC

Some concern about PK and Index correct me if i am wrong when we create table index is created implicitly whether we set a PK or not...if its the case y we need to create Index explicitly if i think that explicit index is good for performance than what do we use for imlicit one...Thanks alot

Tom Kyte
August 16, 2002 - 10:51 am UTC

When you create a table, without a primary key, there will be NO index created.

An index will be created for a primary key constraint if and only if no existing index exists that would suffice.

Unique Index and Unique Constraint

Fan, July 31, 2003 - 9:31 pm UTC

Tom,

Considering the following two statement will achieve the same results of enforcing unique values in column a. What do you think the benefit of the first one of having a constraint in the table? Thanks.


1. alter table t add (constraint t_uk unique (a) using index (create unique index t_ix1 on t (a) ))
2. create unique index t_ix1 on t (a);


Previously I always used only unique indexes without unique constraints. Is it good approach?

Tom Kyte
August 01, 2003 - 7:36 am UTC

#1 is the only correct and proper way to do it.

</code> http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:4941517587762 <code>

you should use a CONSTRAINT, the index is incidental and may not even be needed.

unique index is a misnomer

mikito harakiri, August 01, 2003 - 4:33 pm UTC

What is justification for "unique index" concept?

Index is just a B-tree. We can have functional indexes, composite indexes (which are disguised form of functional indexes:-), bitmap indexes, etc. However, mixing constraint idea with access path idea todether is just wrong.

Tom Kyte
August 01, 2003 - 5:00 pm UTC

internally -- all indexes are unique actually.


"create unique index" -- implies the rowid is part of the functionally dependent data in the index, the rowid is not part of the key.

"create index" -- implies the rowid is part of the key, ensuring each entry is in fact unique.


A composite or concatenated index is not a disguised form of function based indexes, I don't understand that comment. they are just indexes with a key defined as more then one column.


But agreed -- a constraint is a constraint and should be specified as such. An index is an index -- used to "tune"

index rows ordered also by rowid ?

Alberto Dell'Era, August 01, 2003 - 5:37 pm UTC

> "create index" -- implies the rowid is part of the key,
> ensuring each entry is in fact unique.

Does this mean that the rows of the index are ordered
by rowid also, i.e. the indexed columns with equal
values are stored in the index sorted by rowid, and
not "randomly" ?

Tom Kyte
August 01, 2003 - 7:06 pm UTC

I'll never tell ;)

it would not be anything you could ever rely on.

the only way you can ensure the order of rows from a query is to use an ORDER BY....

perhaps you may tell if I explain myself better ... ;-)

Alberto Dell'Era, August 02, 2003 - 5:46 am UTC

> the only way you can ensure the order of rows from a query
> is to use an ORDER BY....

Of course ... actually i was thinking about a range-scan; since pinning the "pointed by the rowids" table buffers is a relatively expensive operation (since you must get the corresponding cache buffer latch), if the rows were ordered by rowid (and so by block, essentially), simply visiting the index rows as they are stored would be enough to minimize the number of pins, increasing the scalability.

So your telling would not distract me from the Road to Knowledge ;-), quite the opposite ...





Tom Kyte
August 02, 2003 - 9:04 am UTC

actually -- in 9i, what you will find is the table access by rowid is moved out as far as possible in many query plans -- meaning, we'll scan and get a bunch of rowid together and then "bulk get" the corresponding rows -- further enhancing this concept (that is new with the cbo in 9i)

(but yes, the rowid will be the last part of the key in the b*tree with a non-unique index like that. hypothesis is accurate)

got the point

Alberto Dell'Era, August 02, 2003 - 9:29 am UTC

So, Oracle will try to minimize the pins of the table buffers, and whether this is done by ordering the index rows also by rowid, or using the new "bulk get" feature of 9i you mention, it is inessential for us, database data developers.

And the "index rows ordering by rowid" may be no more the case in 9i [even assuming that it were performed on previous releases ...] since there's now the new "bulk get" CBO feature.

Thanks!

Very useful discussion, thanks!

David Rydzewski, September 12, 2003 - 9:39 am UTC


How does one find the name (if any) of an index used by a PK

mike, February 25, 2004 - 12:33 pm UTC

My company has created a "database normalizer" which
extracts schema information from our "perfect" database,
and uses this information to make adjustments to databases
that are being upgraded. For example, we check for missing
and/or extra indexes on tables and add/drop them as needed.
Until now, our assumption has been that a PK constraint always had an analogous entry in USER_INDEXES, and we have
just run into a case where this is not true. Is there
a way to determine the name of an index being used by a PK
constraint if it has "chosen" one which already exists?

Tom Kyte
February 25, 2004 - 12:39 pm UTC

select index_name from user_constraints ....

(what version do you have -- that was added in 9i)

Just what I was hoping for

Mike, February 25, 2004 - 12:45 pm UTC

Nice to know that you have added the INDEX_NAME to
USER_CONSTRAINTS in 9i. Most of our sites are 8i,
though they will over time eventually move to newer
versions of Oracle. I think the solution is to
have our "normalizer" not panic if it is unable
to find an index in USERS_INDEXES with the same name
as the constraint. Right now we treat that as a error
condition. Thanks for your very helpful discussions
on the ORA-02270 errors. I feel much more educated
on the subject now...

Why not function-based constraints?

Andrew, February 25, 2004 - 3:35 pm UTC

Muddying the constraint/index waters a bit further, I have
encountered the following requirements designing tables:

- Table rows are uniquely identified by a "name"
- Uniqueness must NOT be dependent on case
- Original case of the name must be preserved for the sake
of presentation

My typical approach in this situation is something like:

CREATE TABLE entity
( id NUMBER(10)
CONSTRAINT pk_entity
PRIMARY KEY,
name VARCHAR2(30)
CONSTRAINT nn_entity_name
NOT NULL
)
/

CREATE UNIQUE INDEX ux_entity_uppname
ON entity
( UPPER( name ) )
/

Without the luxury (necessity?) of function-based indexes,
I suppose you would be forced to define a second column,
say "uppname", and maintain it with triggers. Having the
luxury, I would rather define only the one "name" column,
add the index, and then be able to say:

--Hypothetical code
ALTER TABLE entity
ADD
( CONSTRAINT nk_entity_uppname
UNIQUE
( UPPER( name ) )
)

The compromise in my typical approach is not so much in
functionality--the unique, function-based index works like
a charm. I'm just concerned that I have an index enforcing
a database constraint that can't be declared explicitly.

Do you have a preferred approach to this situation? Thanks
in advance for any comments.



Tom Kyte
February 25, 2004 - 5:23 pm UTC

Oh, I do that myself (the fbi)

when you CAN use a constraint -- by all means USE it.

when you cannot use a constraint, by all means find the most efficient method to implement your needs - and the FBI fills that bill quite nicely.

Unique Index v/s. Unique Constraint

Vivek Sharma, May 29, 2004 - 2:12 pm UTC

Dear Tom,

Chapter 10 of Oracle 9i Documentation on Indexes states that

</code> http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96524/c11schem.htm <code>

"Oracle recommends that unique indexes be created explicitly, and not through enabling a unique constraint on a table.

Alternatively, you can define UNIQUE integrity constraints on the desired columns. Oracle enforces UNIQUE integrity constraints by automatically defining a unique index on the unique key. However, it is advisable that any index that exists for query performance, including unique indexes, be created explicitly."

What is the reason behind this ? What is the difference between the 2 methods of creating an Indexes either directly or using a constraint ?

and does it relates to the performance ?

Thanks and Regards
Vivek


Tom Kyte
May 30, 2004 - 10:19 am UTC

the recommendation is perhaps poorly worded. it should be:


"If you want a unique index, really really want a unique index, please create it explicitly because the creation of a unique constraint or primary key won't necessary create one as most people believe"

The difference is a constraint *might* or *might not* create an index.

The only thing that assures an index is in fact created on those exact columns, using "unique" would be a create unique index statement.

Overhead?

John, September 05, 2017 - 8:11 am UTC

Is there any overhead in the maintenance of a unique key rather than a unique index (or vice versa)?

I have a table like this:
create table blah (
  id number not null,
  line_no number not null,
  version_no number not null,
  description varchar2(100),
  constraint blah_pk primary key (id)
);

now I also know that the combination of line_no and version_no must be unique (though I want to retain a single column as the pk). So I can either add a unique index on the table, or a unique key.
alter table blah add (constraint blah_u1 unique(line_no,version_no));

or
create unique index blah_u1 on blah(line_no,version_no);


neither of those columns need to be foreign key'ed to anything - I just want to enforce uniqueness at the db level.

Would it be preferable to use the key or an index in such a situation?


Chris Saxon
September 05, 2017 - 11:50 am UTC

Well creating a unique constraint also creates a unique index to police it:

create table blah (
  id number not null,
  line_no number not null,
  version_no number not null,
  description varchar2(100),
  constraint blah_pk primary key (id)
);

alter table blah add (constraint blah_u1 unique(line_no,version_no));

select uniqueness from user_indexes
where  index_name = 'BLAH_U1';

UNIQUENESS  
UNIQUE      


So the index maintenance is the same!

Personally, I'd go with the constraint. This more accurately reflects your intent. And allows you to point FKs to it in the future should you want to.