Обсуждение: Strange Execution-Plan for NOT EXISTS

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

Strange Execution-Plan for NOT EXISTS

От
Jens Hartwig
Дата:
Hello all,

I tried (just for academical fun) to resolve ID´s which are not used
anymore, e.g.:

ID   NAME
-- + ------------------
1  | NOBODY
2  | ANYBODY
4  | EVERYBODY

Now I want to get "3" as the next usable ID. I really know that this is
kind of bad style but a friend of mine asked me if I had a solution for
this problem.

My solution would be the following statement:

--------------------------------
select (min(id) + 1)
from t_dummy d1
where not exists (   select id   from t_dummy d2   where d2.id = (d1.id + 1)
);
--------------------------------

The explain plan for this statement, tested against a real table with
about 8,000 records in a freshly vacuumed database, looks like the
following:

Aggregate  (cost=2924207.88..2924207.88 rows=1 width=12) ->  Seq Scan on t_dummy d1  (cost=0.00..2924207.88 rows=1
width=12)      SubPlan         ->  Seq Scan on t_dummy d2  (cost=0.00..331.36 rows=1 width=12
 
)

Why that? Wouldn´t it be possible to simple use the primary key index in
the sub-query and exit from the outer query at the first occurence of an
ID which has no following entry? Any ideas from anyone? Am I wrong?

Best regards, Jens

=============================================
Jens Hartwig
---------------------------------------------
debis Systemhaus GEI mbH
10875 Berlin
Tel.     : +49 (0)30 2554-3282
Fax      : +49 (0)30 2554-3187
Mobil    : +49 (0)170 167-2648
E-Mail   : jhartwig@debis.com
=============================================


Re: Strange Execution-Plan for NOT EXISTS

От
Tom Lane
Дата:
Jens Hartwig <jhartwig@debis.com> writes:
> select (min(id) + 1)
> from t_dummy d1
> where not exists (
>     select id
>     from t_dummy d2
>     where d2.id = (d1.id + 1)
> );

> Aggregate  (cost=2924207.88..2924207.88 rows=1 width=12)
-> Seq Scan on t_dummy d1  (cost=0.00..2924207.88 rows=1 width=12)
>         SubPlan
>           -> Seq Scan on t_dummy d2  (cost=0.00..331.36 rows=1 width=12)

> Why that? Wouldn�t it be possible to simple use the primary key index in
> the sub-query

I think that 7.0.* is too stupid to consider an indexscan for a
qualifier that looks like "indexvar = ($1 + 1)", which is what you
effectively have in this case ($1 being the Param passed in from
the outer plan).  It only recognizes "indexvar = constant" and
"indexvar = param" as indexable expressions.  Current sources do
better.
        regards, tom lane