mirror of
https://github.com/postgres/postgres.git
synced 2025-12-21 05:21:08 +03:00
Teach UNION planner to remove dummy inputs
This adjusts UNION planning so that the planner produces more optimal plans when one or more of the UNION's subqueries have been proven to be empty (a dummy rel). If any of the inputs are empty, then that input can be removed from the Append / MergeAppend. Previously, a const-false "Result" node would appear to represent this. Removing empty inputs has a few extra benefits when only 1 union child remains as it means the Append or MergeAppend can be removed in setrefs.c, making the plan slightly faster to execute. Also, we can provide better n_distinct estimates by looking at the sole remaining input rel's statistics. Author: David Rowley <dgrowleyml@gmail.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/CAApHDvri53PPF76c3M94_QNWbJfXjyCnjXuj_2=LYM-0m8WZtw@mail.gmail.com
This commit is contained in:
@@ -1216,6 +1216,57 @@ select event_id
|
||||
|
||||
drop table events_child, events, other_events;
|
||||
reset enable_indexonlyscan;
|
||||
--
|
||||
-- Test handling of UNION with provably empty inputs
|
||||
--
|
||||
-- Ensure the empty UNION input is pruned and de-duplication is done for the
|
||||
-- remaining relation.
|
||||
EXPLAIN (COSTS OFF, VERBOSE)
|
||||
SELECT two FROM tenk1 WHERE 1=2
|
||||
UNION
|
||||
SELECT four FROM tenk1
|
||||
ORDER BY 1;
|
||||
QUERY PLAN
|
||||
--------------------------------------
|
||||
Sort
|
||||
Output: tenk1.four
|
||||
Sort Key: tenk1.four
|
||||
-> HashAggregate
|
||||
Output: tenk1.four
|
||||
Group Key: tenk1.four
|
||||
-> Seq Scan on public.tenk1
|
||||
Output: tenk1.four
|
||||
(8 rows)
|
||||
|
||||
-- Validate that the results of the above are correct
|
||||
SELECT two FROM tenk1 WHERE 1=2
|
||||
UNION
|
||||
SELECT four FROM tenk1
|
||||
ORDER BY 1;
|
||||
two
|
||||
-----
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
(4 rows)
|
||||
|
||||
-- All UNION inputs are proven empty. Ensure the planner provides a
|
||||
-- const-false Result node
|
||||
EXPLAIN (COSTS OFF, VERBOSE)
|
||||
SELECT two FROM tenk1 WHERE 1=2
|
||||
UNION
|
||||
SELECT four FROM tenk1 WHERE 1=2
|
||||
UNION
|
||||
SELECT ten FROM tenk1 WHERE 1=2;
|
||||
QUERY PLAN
|
||||
--------------------------------
|
||||
Result
|
||||
Output: unnamed_subquery.two
|
||||
Replaces: Aggregate
|
||||
One-Time Filter: false
|
||||
(4 rows)
|
||||
|
||||
-- Test constraint exclusion of UNION ALL subqueries
|
||||
explain (costs off)
|
||||
SELECT * FROM
|
||||
|
||||
@@ -459,6 +459,33 @@ drop table events_child, events, other_events;
|
||||
|
||||
reset enable_indexonlyscan;
|
||||
|
||||
--
|
||||
-- Test handling of UNION with provably empty inputs
|
||||
--
|
||||
|
||||
-- Ensure the empty UNION input is pruned and de-duplication is done for the
|
||||
-- remaining relation.
|
||||
EXPLAIN (COSTS OFF, VERBOSE)
|
||||
SELECT two FROM tenk1 WHERE 1=2
|
||||
UNION
|
||||
SELECT four FROM tenk1
|
||||
ORDER BY 1;
|
||||
|
||||
-- Validate that the results of the above are correct
|
||||
SELECT two FROM tenk1 WHERE 1=2
|
||||
UNION
|
||||
SELECT four FROM tenk1
|
||||
ORDER BY 1;
|
||||
|
||||
-- All UNION inputs are proven empty. Ensure the planner provides a
|
||||
-- const-false Result node
|
||||
EXPLAIN (COSTS OFF, VERBOSE)
|
||||
SELECT two FROM tenk1 WHERE 1=2
|
||||
UNION
|
||||
SELECT four FROM tenk1 WHERE 1=2
|
||||
UNION
|
||||
SELECT ten FROM tenk1 WHERE 1=2;
|
||||
|
||||
-- Test constraint exclusion of UNION ALL subqueries
|
||||
explain (costs off)
|
||||
SELECT * FROM
|
||||
|
||||
Reference in New Issue
Block a user