Обсуждение: partial index on boolean, problem with v8.0.0rc1

Поиск
Список
Период
Сортировка

partial index on boolean, problem with v8.0.0rc1

От
Igor Shevchenko
Дата:
Hi all,

PostgreSQL v8.0.0rc1, two variants of a "user_msg" table:

create table user_msg (
  message_id integer not null references message(id) on update cascade on
delete cascade,
  user_id integer not null,
  status smallint not null default 0,
  is_read boolean not null default false,
  unique (message_id,user_id)
);
create index user_msg_is_read_idx on user_msg(is_read) where is_read=true;


create table user_msg (
  message_id integer not null references message(id) on update cascade on
delete cascade,
  user_id integer not null,
  status smallint,
  is_read boolean,
  unique (message_id,user_id)
);
create index user_msg_is_read_idx on user_msg(is_read) where is_read=true;


In both cases, tables are filled with ~10m of rows, "is_read" is false in the
1st case, and "NULL" in the 2nd. I did "VACUUM FULL ANALYSE" after both
imports.

Here's the problem: in the 2nd case, planner wouldn't choose an index scan
using partial index on "is_read" for the following queries:

explain select * from user_msg where is_read=true;
explain select * from user_msg where is_read is true;
explain select * from user_msg where is_read;

In the 1st case, partial index was used for the first query.

--
Best Regards,
Igor Shevchenko

Re: partial index on boolean, problem with v8.0.0rc1

От
Bruno Wolff III
Дата:
On Mon, Dec 13, 2004 at 20:18:57 +0200,
  Igor Shevchenko <igor@carcass.ath.cx> wrote:
>
> Here's the problem: in the 2nd case, planner wouldn't choose an index scan
> using partial index on "is_read" for the following queries:
>
> explain select * from user_msg where is_read=true;
> explain select * from user_msg where is_read is true;
> explain select * from user_msg where is_read;
>
> In the 1st case, partial index was used for the first query.

Note that whatever = TRUE is not equivalent to whatever IS TRUE.
The latter will return FALSE if whatever is NULL, while the former will return
NULL in that case.

There are also some limitations on the optimizer recognizing equivalent
varients of an expression. This might cause a problem with the third
select example.

Re: partial index on boolean, problem with v8.0.0rc1

От
Tom Lane
Дата:
Igor Shevchenko <igor@carcass.ath.cx> writes:
> In both cases, tables are filled with ~10m of rows, "is_read" is false in the
> 1st case, and "NULL" in the 2nd. I did "VACUUM FULL ANALYSE" after both
> imports.

> Here's the problem: in the 2nd case, planner wouldn't choose an index scan
> using partial index on "is_read" for the following queries:

This is the same problem noted by Mike Mascari a couple weeks ago:
ANALYZE does not store any statistics about an all-null column.
So there are no stats and the default decision is not to risk an
indexscan

> explain select * from user_msg where is_read=true;
> explain select * from user_msg where is_read is true;
> explain select * from user_msg where is_read;

Only the first of these could possibly match the partial index anyway.
In theory the planner could recognize that the first and third are
equivalent spellings of the same condition, but it does not presently
do so.

            regards, tom lane