pg.ddx.io  pgsql-performance@postgresql.org mailing list archive  
help / color / mirror / Atom feed
Constraint 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