6 15.3.3. Parallel Aggregation
7 15.3.4. Parallel Append
8 15.3.5. Parallel Plan Tips
10 Because each worker executes the parallel portion of the plan to
11 completion, it is not possible to simply take an ordinary query plan
12 and run it using multiple workers. Each worker would produce a full
13 copy of the output result set, so the query would not run any faster
14 than normal but would produce incorrect results. Instead, the parallel
15 portion of the plan must be what is known internally to the query
16 optimizer as a partial plan; that is, it must be constructed so that
17 each process that executes the plan will generate only a subset of the
18 output rows in such a way that each required output row is guaranteed
19 to be generated by exactly one of the cooperating processes. Generally,
20 this means that the scan on the driving table of the query must be a
23 15.3.1. Parallel Scans #
25 The following types of parallel-aware table scans are currently
27 * In a parallel sequential scan, the table's blocks will be divided
28 into ranges and shared among the cooperating processes. Each worker
29 process will complete the scanning of its given range of blocks
30 before requesting an additional range of blocks.
31 * In a parallel bitmap heap scan, one process is chosen as the
32 leader. That process performs a scan of one or more indexes and
33 builds a bitmap indicating which table blocks need to be visited.
34 These blocks are then divided among the cooperating processes as in
35 a parallel sequential scan. In other words, the heap scan is
36 performed in parallel, but the underlying index scan is not.
37 * In a parallel index scan or parallel index-only scan, the
38 cooperating processes take turns reading data from the index.
39 Currently, parallel index scans are supported only for btree
40 indexes. Each process will claim a single index block and will scan
41 and return all tuples referenced by that block; other processes can
42 at the same time be returning tuples from a different index block.
43 The results of a parallel btree scan are returned in sorted order
44 within each worker process.
46 Other scan types, such as scans of non-btree indexes, may support
47 parallel scans in the future.
49 15.3.2. Parallel Joins #
51 Just as in a non-parallel plan, the driving table may be joined to one
52 or more other tables using a nested loop, hash join, or merge join. The
53 inner side of the join may be any kind of non-parallel plan that is
54 otherwise supported by the planner provided that it is safe to run
55 within a parallel worker. Depending on the join type, the inner side
56 may also be a parallel plan.
57 * In a nested loop join, the inner side is always non-parallel.
58 Although it is executed in full, this is efficient if the inner
59 side is an index scan, because the outer tuples and thus the loops
60 that look up values in the index are divided over the cooperating
62 * In a merge join, the inner side is always a non-parallel plan and
63 therefore executed in full. This may be inefficient, especially if
64 a sort must be performed, because the work and resulting data are
65 duplicated in every cooperating process.
66 * In a hash join (without the "parallel" prefix), the inner side is
67 executed in full by every cooperating process to build identical
68 copies of the hash table. This may be inefficient if the hash table
69 is large or the plan is expensive. In a parallel hash join, the
70 inner side is a parallel hash that divides the work of building a
71 shared hash table over the cooperating processes.
73 15.3.3. Parallel Aggregation #
75 PostgreSQL supports parallel aggregation by aggregating in two stages.
76 First, each process participating in the parallel portion of the query
77 performs an aggregation step, producing a partial result for each group
78 of which that process is aware. This is reflected in the plan as a
79 Partial Aggregate node. Second, the partial results are transferred to
80 the leader via Gather or Gather Merge. Finally, the leader
81 re-aggregates the results across all workers in order to produce the
82 final result. This is reflected in the plan as a Finalize Aggregate
85 Because the Finalize Aggregate node runs on the leader process, queries
86 that produce a relatively large number of groups in comparison to the
87 number of input rows will appear less favorable to the query planner.
88 For example, in the worst-case scenario the number of groups seen by
89 the Finalize Aggregate node could be as many as the number of input
90 rows that were seen by all worker processes in the Partial Aggregate
91 stage. For such cases, there is clearly going to be no performance
92 benefit to using parallel aggregation. The query planner takes this
93 into account during the planning process and is unlikely to choose
94 parallel aggregate in this scenario.
96 Parallel aggregation is not supported in all situations. Each aggregate
97 must be safe for parallelism and must have a combine function. If the
98 aggregate has a transition state of type internal, it must have
99 serialization and deserialization functions. See CREATE AGGREGATE for
100 more details. Parallel aggregation is not supported if any aggregate
101 function call contains DISTINCT or ORDER BY clause and is also not
102 supported for ordered set aggregates or when the query involves
103 GROUPING SETS. It can only be used when all joins involved in the query
104 are also part of the parallel portion of the plan.
106 15.3.4. Parallel Append #
108 Whenever PostgreSQL needs to combine rows from multiple sources into a
109 single result set, it uses an Append or MergeAppend plan node. This
110 commonly happens when implementing UNION ALL or when scanning a
111 partitioned table. Such nodes can be used in parallel plans just as
112 they can in any other plan. However, in a parallel plan, the planner
113 may instead use a Parallel Append node.
115 When an Append node is used in a parallel plan, each process will
116 execute the child plans in the order in which they appear, so that all
117 participating processes cooperate to execute the first child plan until
118 it is complete and then move to the second plan at around the same
119 time. When a Parallel Append is used instead, the executor will instead
120 spread out the participating processes as evenly as possible across its
121 child plans, so that multiple child plans are executed simultaneously.
122 This avoids contention, and also avoids paying the startup cost of a
123 child plan in those processes that never execute it.
125 Also, unlike a regular Append node, which can only have partial
126 children when used within a parallel plan, a Parallel Append node can
127 have both partial and non-partial child plans. Non-partial children
128 will be scanned by only a single process, since scanning them more than
129 once would produce duplicate results. Plans that involve appending
130 multiple result sets can therefore achieve coarse-grained parallelism
131 even when efficient partial plans are not available. For example,
132 consider a query against a partitioned table that can only be
133 implemented efficiently by using an index that does not support
134 parallel scans. The planner might choose a Parallel Append of regular
135 Index Scan plans; each individual index scan would have to be executed
136 to completion by a single process, but different scans could be
137 performed at the same time by different processes.
139 enable_parallel_append can be used to disable this feature.
141 15.3.5. Parallel Plan Tips #
143 If a query that is expected to do so does not produce a parallel plan,
144 you can try reducing parallel_setup_cost or parallel_tuple_cost. Of
145 course, this plan may turn out to be slower than the serial plan that
146 the planner preferred, but this will not always be the case. If you
147 don't get a parallel plan even with very small values of these settings
148 (e.g., after setting them both to zero), there may be some reason why
149 the query planner is unable to generate a parallel plan for your query.
150 See Section 15.2 and Section 15.4 for information on why this may be
153 When executing a parallel plan, you can use EXPLAIN (ANALYZE, VERBOSE)
154 to display per-worker statistics for each plan node. This may be useful
155 in determining whether the work is being evenly distributed between all
156 plan nodes and more generally in understanding the performance
157 characteristics of the plan.