On 28 July 2015 at 09:37, Frédéric TERRAZZONI <frederic.terrazz...@gmail.com
> wrote:

>
>     SELECT * FROM t1
>     WHERE EXISTS(
>         SELECT 1 FROM t2, t3, t4
>         WHERE t2.id = t1.t2_id
>         AND t3.id = t2.t3_id
>         AND t4.id = t3.t4_id
>         AND t4.val = 'XYZ'
>     ) AND EXISTS(
>         SELECT 1 FROM t2, t3, t5
>         WHERE t2.id = t1.t2_id
>         AND t3.id = t2.t3_id
>         AND t5.id = t3.t5_id
>         AND t5.val = 'Blablabla'
>     ) AND EXISTS(
>         SELECT 1 FROM t6
>         WHERE t6.id = t1.t6_id
>         AND t6.val = 'Hello'
>     )
>
> ...


>
> The resulting query is:
>
>     SELECT * FROM t1
>         WHERE EXISTS(
>             SELECT 1 FROM t2 t2_a, t3 t3_a, t4 t4_a, t2 t2_b, t3 t3_b, t5,
> t6
>             WHERE t2_a.id = t1.t2_id
>             AND t3_a.id = t2_a.t3_id
>             AND t4_a.id = t3_a.t4_id
>             AND t4_a.val = 'XYZ'
>             AND t2_b.id = t1.t2_id
>             AND t3_b.id = t2_b.t3_id
>             AND t5.id = t3_b.t5_id
>             AND t5.val = 'Blablabla'
>             AND t6.id = t1.t6_id
>             AND t6.val = 'Hello'
>         )
>
> My questions are:
> - Does PostgreSQL already supports this optimization ? Maybe it's not
> enabled in my case only?
>

No, there's nothing which supports that currently.


> - If yes, is my reasoning incorrect ? Can you point me my mistake ?
>

It sounds reasonable to me.


> - Otherwise is there any plan to add this optimization to PostgreSQL ?
>
>
I did propose the idea here
http://www.postgresql.org/message-id/CAApHDvopmWq4i2BCf0VqU4mYmxzHCYwfnUMat9TWuKzdvo7=8...@mail.gmail.com
but I didn't focus just with semi-joins. Without re-reading, I think I was
talking about any join that could be proved to not duplicate rows could be
"consolidated".

I do believe that this optimisation would be useful in more cases than most
people might think, for example:

UPDATE t1 SET col1 = (SELECT col1 FROM t2 WHERE t1.id=t2.id), col2 =
(SELECT col2 FROM t2 WHERE t1.id=t2.id), ...;

Of course, this query could have been written using UPDATE/FROM,
(non-standard), or UPDATE t1 SET (col1,col2) = (SELECT ...), which was only
added recently.

There's also the case of the view which just has 1 column missing, so the
consumer joins a table that's already been joined to in the view.

I think it would be quite nice to have this, and I don't think it would be
all that expensive for the planner to detect this.

I think the planner would have to do something like:

1. Scan simple_rte_array looking for relids which are the same as another
entry's.
2. If found, is the join condition the same as the other one?
3. Is there a unique index to prove that joining to this does not duplicate
rows, or is it a semi-join?
4. Remove relation and replace all Vars from the removed relation with the
one from the other table, mark relation as REL_DEAD.

I think 1 is quite cheap to perform, so normal queries wouldn't suffer much
of a slow-down from these extra checks, as most queries won't have self
joins.

Are you thinking of working on it?

Regards

David Rowley

--
 David Rowley                   http://www.2ndQuadrant.com/
<http://www.2ndquadrant.com/>
 PostgreSQL Development, 24x7 Support, Training & Services

Reply via email to