Skip to Main Content
  • Questions
  • How does Oracle know whether the index belongs to the primary key?

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Valentin.

Asked: February 08, 2017 - 2:01 pm UTC

Last updated: November 28, 2022 - 6:01 am UTC

Version: 11g

Viewed 1000+ times

You Asked

Consider the following two tables and their primary keys:
create table testuser.test1 (
    col1 number not null,
    col2 number not null,
    col3 number not null
);
alter table testuser.test1
    add constraint test1_pk primary key (col1);

create table testuser.test2 (
    col1 number not null,
    col2 number not null,
    col3 number not null
);
create unique index testuser.test2_pk on testuser.test2 (col1);
alter table testuser.test2
    add constraint test2_pk primary key (col1)
    using index testuser.test2_pk;

Note that my index has the same name than my primary key: test2_pk.
If I compare the constraints and the indices, I cannot see any difference between the "automatic" index test1_pk and the "manual" index test2_pk.
select * from dba_indexes where table_owner = 'TESTUSER' and lower(index_name) like '%test%';
select * from dba_constraints where owner = 'TESTUSER' and lower(constraint_name) like '%test%';

But obviously, Oracle can tell the difference, because if I now drop the primary keys and check my indices again:
alter table testuser.test1 drop constraint test1_pk;
alter table testuser.test2 drop constraint test2_pk;

select * from dba_indexes where table_owner = 'TESTUSER' and lower(index_name) like '%test%';

the "automatic" index test1_pk is gone, but the "manual" index test2_pk is still here (as it should)


My question is: How can I know if an index is "automatic" (i.e. will be dropped when dropping the primary key) or "manual" (won't be dropped when dropping the primary key) ?

and Connor said...

Its not visible in the standard views. (You can see the differences by looking at the data in the tables that underpin those views).

So rather than querying whether it will, you can have explicit control yourself using the "keep index" and "drop index" clauses when you want to drop a constraint.

Rating

  (4 ratings)

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

Comments

Which tables?

Valentin Decaillet, February 14, 2017 - 7:52 am UTC

Thanks for your answer.

>> You can see the differences by looking at the data in the tables that underpin those views.
Sorry for the stupid question: what are these tables? How do I query them?

But on a larger scope, your advice (using "drop index") seemed to be the way to go for me.
Connor McDonald
February 15, 2017 - 3:45 am UTC

Well... they're not documented for a reason :-) It's the internal dictionary tables, so it would be 'inappropriate' for me to go into details of them.

But of course, just about *every* view is defined in DBA_VIEWS, so of course I can't stop you from looking up their definition, then running some queries on the underlying tables directly.

(hint hint)

:-)

Thanks

Valentin Decaillet, February 15, 2017 - 8:26 am UTC

Ok, thanks very much for the additional info and the 'inappropriate' answer...

Cheers ;)

Disagree about index pk visibility

alexandre guerra, November 22, 2022 - 1:53 pm UTC

I believe that a single boolean (YN) column in dba_indexes , is truly useful. I (respectfully) disagree not exposing this for knowledge (not for change) . It should...
Connor McDonald
November 25, 2022 - 5:19 am UTC

Head over to database ideas https://community.oracle.com/tech/apps-infra/categories/database-ideas-ideas and log a request for it

SYS.IND$.PROPERTY

A reader, November 25, 2022 - 9:26 am UTC

create table t1(n1 number, n2 number);
create unique index t1n1 on t1(n1);
alter table t1 add constraint t1n1 unique (n1) using index t1n1;
alter table t1 add constraint t1n2 unique (n2);

select index_name, bitand(xmlcast(xmltype(dbms_metadata.get_xml('INDEX',index_name)).extract('/ROWSET/ROW/INDEX_T/PROPERTY/text()') as number),4096) cons
from user_indexes where table_name='T1';

INDEX_NAME       CONS
---------- ----------
T1N1                0
T1N2             4096

-- since 19c
select index_name, constraint_index from user_indexes where table_name = 'T1';

INDEX_NAME CONSTRAINT_INDEX
---------- ----------------
T1N1       NO              
T1N2       YES             

Connor McDonald
November 28, 2022 - 6:01 am UTC

"so of course I can't stop you from looking up their definition, then running some queries on the underlying tables directly."

:-)