Re: BUG #17540: Prepared statement: PG switches to a generic query plan which is consistently much slower
От | David Rowley |
---|---|
Тема | Re: BUG #17540: Prepared statement: PG switches to a generic query plan which is consistently much slower |
Дата | |
Msg-id | CAApHDvpkfS1hY3P4DWbOw6WCgRrja=yDLoEz+5g+E2z19Upsrg@mail.gmail.com обсуждение исходный текст |
Ответ на | Re: BUG #17540: Prepared statement: PG switches to a generic query plan which is consistently much slower (Richard Guo <guofenglinux@gmail.com>) |
Ответы |
Re: BUG #17540: Prepared statement: PG switches to a generic query plan which is consistently much slower
|
Список | pgsql-bugs |
On Mon, 10 Jul 2023 at 18:39, Richard Guo <guofenglinux@gmail.com> wrote: > Here is v3 patch with regression tests. I add the new test into the > group where stats test is in, but I'm not sure if this is the right > place. Thanks for taking an interest in this. I spent more time looking at the idea and I wondered why we should just have it skip distributing IS NOT NULL quals to the relations. Should we also be allow IS NULL quals on non-nullable Vars to be detected as false? I did some work on your v3 patch to see if that could be made to work. I ended up just trying to make a new RestrictInfo with a "false" clause, but quickly realised that it's not safe to go making new RestrictInfos during deconstruct_distribute_oj_quals(). A comment there mentions: /* * Each time we produce RestrictInfo(s) from these quals, reset the * last_rinfo_serial counter, so that the RestrictInfos for the "same" * qual condition get identical serial numbers. (This relies on the * fact that we're not changing the qual list in any way that'd affect * the number of RestrictInfos built from it.) This'll allow us to * detect duplicative qual usage later. */ I ended up moving the function that looks for the NullTest quals in the joinlist out so it's done after the quals have been distributed to the relations. I'm not really that happy with this as if we ever found some way to optimise quals that could be made part of an EquivalenceClass then those quals would have already have been processed to become EquivalenceClasses. I just don't see how to do it earlier as deconstruct_distribute_oj_quals() calls remove_nulling_relids() which changes the Var's varnullingrels causing them to be empty during the processing of the NullTest qual. It's also not so great that the RestrictInfo gets duplicated in: CREATE TABLE t1 (a INT NOT NULL, b INT); CREATE TABLE t2 (c INT NOT NULL, d INT); CREATE TABLE t3 (e INT NOT NULL, f INT); postgres=# EXPLAIN (costs off) SELECT * FROM t1 JOIN t2 ON t1.a = 1 LEFT JOIN t3 ON t2.c IS NULL AND t2.d = 1; QUERY PLAN ------------------------------------------------------- Nested Loop -> Nested Loop Left Join Join Filter: (false AND false AND (t2.d = 1)) -> Seq Scan on t2 -> Result One-Time Filter: false -> Materialize -> Seq Scan on t1 Filter: (a = 1) (9 rows) Adjusting the code to build a new false clause and setting that in the existing RestrictInfo rather than building a new RestrictInfo seems to fix that. I wondered if the duplication was a result of the rinfo_serial number changing. Checking back to the original MinMaxAgg I'm not sure if this is all getting more complex than it's worth or not. I've attached what I've ended up with so far. David David
Вложения
В списке pgsql-bugs по дате отправления: