From: | lucas(at)lucas-nussbaum(dot)net |
---|---|
To: | pgsql-bugs(at)postgresql(dot)org |
Subject: | BUG #14608: no index scan with NOT IN and ENUM |
Date: | 2017-03-31 18:53:01 |
Message-ID: | 20170331185301.2690.64421@wrigleys.postgresql.org |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-bugs |
The following bug has been logged on the website:
Bug reference: 14608
Logged by: Lucas Nussbaum
Email address: lucas(at)lucas-nussbaum(dot)net
PostgreSQL version: 9.6.2
Operating system: Linux (Debian stretch)
Description:
Hi,
I augment pgbench's pgbench_accounts table with an additional column that
only contains '0', '1', '2', '3' or '4'.
I set the type of this column to enum('0', '1', '2', '3', '4').
I forbid null values.
I set an index on that column.
When I do:
explain analyze select * from tt where d = '0';
the index is used, as expected.
When I do:
explain analyze select * from tt where d not in ('1', '2', '3', '4');
(which should always produce the same result as the previous query)
the index is not used and a seq scan + filter is used instead.
I would expect postgresql to figure out that "not in ('1', '2', '3', '4')"
is equivalent to "d = '0'" given that the column is NOT NULL. And use the
index.
The following code demonstrates this:
# initialize database
pgbench -i -s 100 bench
# create table from pgbench data
create table tt as select *, (aid%5)::text as d from pgbench_accounts ;
# remove lots of '0' rows (this isn't relevant, in the end, but I thought it
might)
delete from tt where d='0' and aid % 100000 <> 0;
# change column type and set NOT NULL
create type dt as enum('0', '1', '2', '3', '4');
alter table tt alter column d type dt using d::dt;
alter table tt alter column d set not null;
# add index
create index tt_d ON tt(d);
# check values and frequency:
bench=# select d, count(*) from tt group by d;
d | count
---+---------
0 | 100
3 | 2000000
4 | 2000000
2 | 2000000
1 | 2000000
(5 rows)
First case: explain analyze select * from tt where d = '0';
=> index scan, OK
Second case: explain analyze select * from tt where d not in ('1', '2', '3',
'4');
=> seq scan :-(
Thanks!
Lucas
From | Date | Subject | |
---|---|---|---|
Next Message | Andrew Gierth | 2017-03-31 19:04:04 | Re: BUG #14608: no index scan with NOT IN and ENUM |
Previous Message | Devrim Gündüz | 2017-03-31 17:41:19 | Re: BUG #14548: Install plv8 issue |