0

IBM DB2

C:\>db2 create table public.tab1 (id int not null, col1 int not null)
C:\>db2  create unique index tab1_ix on public.tab1 (id) include (col1)
C:\>db2  alter table public.tab1 add primary key (id)
SQL0598W  Existing index "IN1139.TAB1_IX" is used as the index for the primary
key or a unique key.  SQLSTATE=01550

It is just info, that existing index was used.


POSTGRESQL

db=# create table public.tab1 (id int not null, col1 int not null);
db=# create unique index tab1_ix on public.tab1 (id) include (col1);
db=# alter table public.tab1 add primary key (id);

db=# \d public.tab1;
                Table "public.tab1"
 Column |  Type   | Collation | Nullable | Default
--------+---------+-----------+----------+---------
 id     | integer |           | not null |
 col1   | integer |           | not null |
Indexes:
    "tab1_pkey" PRIMARY KEY, btree (id)
    "tab1_ix" UNIQUE, btree (id) INCLUDE (col1)

PostgreSQL created additional index for primary key.

Why is this important? a) In many cases in explain I have seen if primary key is created then database uses primary key index for queries. But if I drop primary key then unique index and queries run way faster (because of Index Only Scan). b) Additional disk space is used for additional primary key index. c) Every update/insert/delete and two indexes must be updated instead of one.

Questions:

  1. Is there a way I can force PostgreSQL database to use existing index, when primary key is added on table with existing unique index (like in IBM Db2)?
  2. Is there a way I can force PostgreSQL to use unique index (and so use Index Only Scan) instead of primary key index (and using only Index Scan) when queries are executed?
2
  • It has its own syntax if you want to use an existing index. See the docs postgresql.org/docs/current/sql-altertable.html Commented Oct 18, 2023 at 14:27
  • Index-only scans are only effective when many pages of the table are marked as all visible. If that is the case, no force should be needed. Check pg_class.relallvisible, and run VACUUM if necessary. Commented Oct 18, 2023 at 14:40

1 Answer 1

1

PostgreSQL doesn't automatically use an existing unique index for the primary key; you have to do it yourself:

ALTER TABLE public.tab1 ADD PRIMARY KEY USING INDEX tab1_ix;

Of course, you could also not create the index in the first place, since a primary key will add its own index, as you see.

4
  • Thanks this works fine. But now additional problem appears when dropping primary key. In IBM Db2 database there is syntax: "ALTER TABLE public.tab1 DROP PRIMARY KEY" and after this unique index I have created still exists. But on PostgreSQL I see this syntax does not exists and I have to use "ALTER TABLE public.tab1 DROP CONSTRAINT tab1_ix", but if I do this beside primary key, index is also dropped. How to drop primary key without dropping unique index? Commented Oct 27, 2023 at 5:38
  • Different database management systems speak different SQL dialects. Seems like DB2 violates the SQL standard here. Commented Oct 27, 2023 at 6:22
  • Do you have SQL standard definition for drop primary key syntax? I tried to search for iso.org/obp/ui/en/#iso:std:76584:en but interesting SQL standard is only available for purchase. Commented Oct 27, 2023 at 8:49
  • The PostgreSQL syntax conforms to the SQL standard in this case. Yes, you have to buy the standard. Commented Oct 27, 2023 at 8:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.