pg.ddx.io pgsql-performance@postgresql.org mailing list archive
help / color / mirror / Atom feedConstraint exclusion on UNION ALL subqueries with WHERE conditions
5+ messages / 2 participants
[nested] [flat]
* Constraint exclusion on UNION ALL subqueries with WHERE conditions
@ 2011-09-14 17:53 Gunnlaugur Þór Briem <gunnlaugur@gmail.com>
0 siblings, 1 reply; 5+ messages in thread
From: Gunnlaugur Þór Briem @ 2011-09-14 17:53 UTC (permalink / raw)
To: pgsql-performance
Hi,
I did this:
CREATE VIEW unionview AS
SELECT col, otherstuff FROM (heavy subquery)
WHERE col BETWEEN 1 AND 3
UNION ALL
SELECT col, otherstuff FROM (another heavy subquery)
WHERE col BETWEEN 4 AND 6;
hoping that the planner could use the WHERE conditions (like it would use check constraints on tables) to exclude one of the subqueries, for a query like:
SELECT * FROM unionview WHERE col=2;
But it doesn't. (In PostgreSQL 8.4.5, at least.)
Is there a way (currently) to get the planner to use these conditions to exclude subqueries in the UNION ALL? Or is this a case of “sounds nice, but too rare to merit implementing”?
Thanks,
- Gulli
^ permalink raw reply [nested|flat] 5+ messages in thread
* Re: Constraint exclusion on UNION ALL subqueries with WHERE conditions
@ 2011-09-19 03:59 Tom Lane <tgl@sss.pgh.pa.us>
parent: Gunnlaugur Þór Briem <gunnlaugur@gmail.com>
0 siblings, 1 reply; 5+ messages in thread
From: Tom Lane @ 2011-09-19 03:59 UTC (permalink / raw)
To: pgsql-performance
=?ISO-8859-1?Q?Gunnlaugur_=DE=F3r_Briem?= <gunnlaugur@gmail.com> writes:
> I did this:
> CREATE VIEW unionview AS
> SELECT col, otherstuff FROM (heavy subquery)
> WHERE col BETWEEN 1 AND 3
> UNION ALL
> SELECT col, otherstuff FROM (another heavy subquery)
> WHERE col BETWEEN 4 AND 6;
> hoping that the planner could use the WHERE conditions (like it would use check constraints on tables) to exclude one of the subqueries, for a query like:
> SELECT * FROM unionview WHERE col=2;
> But it doesn't. (In PostgreSQL 8.4.5, at least.)
Works for me in 8.4.8. Do you have constraint_exclusion set to ON?
regards, tom lane
^ permalink raw reply [nested|flat] 5+ messages in thread
* Re: Constraint exclusion on UNION ALL subqueries with WHERE conditions
@ 2011-09-20 09:15 Gunnlaugur Þór Briem <gunnlaugur@gmail.com>
parent: Tom Lane <tgl@sss.pgh.pa.us>
0 siblings, 1 reply; 5+ messages in thread
From: Gunnlaugur Þór Briem @ 2011-09-20 09:15 UTC (permalink / raw)
To: pgsql-performance
On Monday, September 19, 2011 3:59:30 AM UTC, Tom Lane wrote:
> Works for me in 8.4.8. Do you have constraint_exclusion set to ON?
I did try with constraint_exclusion set to on, though the docs suggest partition should be enough ("examine constraints only for ... UNION ALL subqueries")
Here's a minimal test case (which I should have supplied in the original post, sorry), tried just now in 8.4.8:
CREATE OR REPLACE VIEW v_heavy_view
AS SELECT (random()*1e5)::integer col
FROM generate_series(1, 1e6::integer);
CREATE OR REPLACE VIEW v_test_constraint_exclusion AS
SELECT col FROM v_heavy_view WHERE col < 3
UNION ALL SELECT col FROM v_heavy_view WHERE col >= 3;
EXPLAIN SELECT * FROM v_test_constraint_exclusion WHERE col=2;
QUERY PLAN
--------------------------------------------------------------------------
Result (cost=0.00..70.04 rows=4 width=4)
-> Append (cost=0.00..70.04 rows=4 width=4)
-> Subquery Scan v_heavy_view (cost=0.00..35.00 rows=2 width=4)
Filter: ((v_heavy_view.col < 3) AND (v_heavy_view.col = 2))
-> Function Scan on generate_series (cost=0.00..20.00 rows=1000 width=0)
-> Subquery Scan v_heavy_view (cost=0.00..35.00 rows=2 width=4)
Filter: ((v_heavy_view.col >= 3) AND (v_heavy_view.col = 2))
-> Function Scan on generate_series (cost=0.00..20.00 rows=1000 width=0)
I want the planner to notice that (v_heavy_view.col >= 3) AND (v_heavy_view.col = 2) can never be satisfied, and skip that subquery.
Regards,
- Gulli
^ permalink raw reply [nested|flat] 5+ messages in thread
* Re: [PERFORM] Constraint exclusion on UNION ALL subqueries with WHERE conditions
@ 2011-09-21 17:11 Tom Lane <tgl@sss.pgh.pa.us>
parent: Gunnlaugur Þór Briem <gunnlaugur@gmail.com>
0 siblings, 1 reply; 5+ messages in thread
From: Tom Lane @ 2011-09-21 17:11 UTC (permalink / raw)
To: pgsql-hackers@postgreSQL.org; +Cc: pgsql-performance
=?ISO-8859-1?Q?Gunnlaugur_=DE=F3r_Briem?= <gunnlaugur@gmail.com> writes:
> On Monday, September 19, 2011 3:59:30 AM UTC, Tom Lane wrote:
>> Works for me in 8.4.8. Do you have constraint_exclusion set to ON?
> I did try with constraint_exclusion set to on, though the docs suggest partition should be enough ("examine constraints only for ... UNION ALL subqueries")
> Here's a minimal test case (which I should have supplied in the original post, sorry), tried just now in 8.4.8:
> CREATE OR REPLACE VIEW v_heavy_view
> AS SELECT (random()*1e5)::integer col
> FROM generate_series(1, 1e6::integer);
> CREATE OR REPLACE VIEW v_test_constraint_exclusion AS
> SELECT col FROM v_heavy_view WHERE col < 3
> UNION ALL SELECT col FROM v_heavy_view WHERE col >= 3;
> EXPLAIN SELECT * FROM v_test_constraint_exclusion WHERE col=2;
Hmm. The reason this particular case doesn't work is that we don't
apply relation_excluded_by_constraints() to functions-in-FROM.
It's only used for plain-table RTEs, not subqueries, functions,
etc. I suspect the complainant's real case involved an unflattenable
subquery.
Probably the rationale for that coding was that only plain tables
could have CHECK constraints; but the portion of the logic that looks
for mutually contradictory scan constraints could apply to non-table
relations.
Should we change the code to make such checks in these cases?
The default behavior (with constraint_exclusion = partition) would
still be to do nothing extra, but it would add planning expense when
constraint_exclusion = on.
regards, tom lane
^ permalink raw reply [nested|flat] 5+ messages in thread
* Re: Constraint exclusion on UNION ALL subqueries with WHERE conditions
@ 2011-09-22 09:43 Gunnlaugur Þór Briem <gunnlaugur@gmail.com>
parent: Tom Lane <tgl@sss.pgh.pa.us>
0 siblings, 0 replies; 5+ messages in thread
From: Gunnlaugur Þór Briem @ 2011-09-22 09:43 UTC (permalink / raw)
To: pgsql-performance
Right, the view that prompted this involved subqueries; the function was just an artificial test case.
That change seems like a good one for sure.
Ideally I'd like to enable it for a particular view rather than incur the planning expense for the whole DB (something like ALTER VIEW foo WITH CONSTRAINT EXCLUSION), but I guess there's no support currently (and not easily added) for such per-object planner settings? The application can just issue SET constraint_exclusion=on; as needed; for my case that's fine, but for DBAs maybe a bit limiting.
Regards,
- Gulli
^ permalink raw reply [nested|flat] 5+ messages in thread
end of thread, other threads:[~2011-09-22 09:43 UTC | newest]
Thread overview: 5+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2011-09-14 17:53 Constraint exclusion on UNION ALL subqueries with WHERE conditions Gunnlaugur Þór Briem <gunnlaugur@gmail.com>
2011-09-19 03:59 ` Tom Lane <tgl@sss.pgh.pa.us>
2011-09-20 09:15 ` Gunnlaugur Þór Briem <gunnlaugur@gmail.com>
2011-09-21 17:11 ` Tom Lane <tgl@sss.pgh.pa.us>
2011-09-22 09:43 ` Gunnlaugur Þór Briem <gunnlaugur@gmail.com>
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox