gooderp18绿色标准版
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
14KB

  1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>15.3. Parallel Plans</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets V1.79.1" /><link rel="prev" href="when-can-parallel-query-be-used.html" title="15.2. When Can Parallel Query Be Used?" /><link rel="next" href="parallel-safety.html" title="15.4. Parallel Safety" /></head><body><div xmlns="http://www.w3.org/TR/xhtml1/transitional" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">15.3. Parallel Plans</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="when-can-parallel-query-be-used.html" title="15.2. When Can Parallel Query Be Used?">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="parallel-query.html" title="Chapter 15. Parallel Query">Up</a></td><th width="60%" align="center">Chapter 15. Parallel Query</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 12.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="parallel-safety.html" title="15.4. Parallel Safety">Next</a></td></tr></table><hr></hr></div><div class="sect1" id="PARALLEL-PLANS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">15.3. Parallel Plans</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="parallel-plans.html#PARALLEL-SCANS">15.3.1. Parallel Scans</a></span></dt><dt><span class="sect2"><a href="parallel-plans.html#PARALLEL-JOINS">15.3.2. Parallel Joins</a></span></dt><dt><span class="sect2"><a href="parallel-plans.html#PARALLEL-AGGREGATION">15.3.3. Parallel Aggregation</a></span></dt><dt><span class="sect2"><a href="parallel-plans.html#PARALLEL-APPEND">15.3.4. Parallel Append</a></span></dt><dt><span class="sect2"><a href="parallel-plans.html#PARALLEL-PLAN-TIPS">15.3.5. Parallel Plan Tips</a></span></dt></dl></div><p>
  3. Because each worker executes the parallel portion of the plan to
  4. completion, it is not possible to simply take an ordinary query plan
  5. and run it using multiple workers. Each worker would produce a full
  6. copy of the output result set, so the query would not run any faster
  7. than normal but would produce incorrect results. Instead, the parallel
  8. portion of the plan must be what is known internally to the query
  9. optimizer as a <em class="firstterm">partial plan</em>; that is, it must be constructed
  10. so that each process which executes the plan will generate only a
  11. subset of the output rows in such a way that each required output row
  12. is guaranteed to be generated by exactly one of the cooperating processes.
  13. Generally, this means that the scan on the driving table of the query
  14. must be a parallel-aware scan.
  15. </p><div class="sect2" id="PARALLEL-SCANS"><div class="titlepage"><div><div><h3 class="title">15.3.1. Parallel Scans</h3></div></div></div><p>
  16. The following types of parallel-aware table scans are currently supported.
  17. </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
  18. In a <span class="emphasis"><em>parallel sequential scan</em></span>, the table's blocks will
  19. be divided among the cooperating processes. Blocks are handed out one
  20. at a time, so that access to the table remains sequential.
  21. </p></li><li class="listitem"><p>
  22. In a <span class="emphasis"><em>parallel bitmap heap scan</em></span>, one process is chosen
  23. as the leader. That process performs a scan of one or more indexes
  24. and builds a bitmap indicating which table blocks need to be visited.
  25. These blocks are then divided among the cooperating processes as in
  26. a parallel sequential scan. In other words, the heap scan is performed
  27. in parallel, but the underlying index scan is not.
  28. </p></li><li class="listitem"><p>
  29. In a <span class="emphasis"><em>parallel index scan</em></span> or <span class="emphasis"><em>parallel index-only
  30. scan</em></span>, the cooperating processes take turns reading data from the
  31. index. Currently, parallel index scans are supported only for
  32. btree indexes. Each process will claim a single index block and will
  33. scan and return all tuples referenced by that block; other processes can
  34. at the same time be returning tuples from a different index block.
  35. The results of a parallel btree scan are returned in sorted order
  36. within each worker process.
  37. </p></li></ul></div><p>
  38. Other scan types, such as scans of non-btree indexes, may support
  39. parallel scans in the future.
  40. </p></div><div class="sect2" id="PARALLEL-JOINS"><div class="titlepage"><div><div><h3 class="title">15.3.2. Parallel Joins</h3></div></div></div><p>
  41. Just as in a non-parallel plan, the driving table may be joined to one or
  42. more other tables using a nested loop, hash join, or merge join. The
  43. inner side of the join may be any kind of non-parallel plan that is
  44. otherwise supported by the planner provided that it is safe to run within
  45. a parallel worker. Depending on the join type, the inner side may also be
  46. a parallel plan.
  47. </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
  48. In a <span class="emphasis"><em>nested loop join</em></span>, the inner side is always
  49. non-parallel. Although it is executed in full, this is efficient if
  50. the inner side is an index scan, because the outer tuples and thus
  51. the loops that look up values in the index are divided over the
  52. cooperating processes.
  53. </p></li><li class="listitem"><p>
  54. In a <span class="emphasis"><em>merge join</em></span>, the inner side is always
  55. a non-parallel plan and therefore executed in full. This may be
  56. inefficient, especially if a sort must be performed, because the work
  57. and resulting data are duplicated in every cooperating process.
  58. </p></li><li class="listitem"><p>
  59. In a <span class="emphasis"><em>hash join</em></span> (without the "parallel" prefix),
  60. the inner side is executed in full by every cooperating process
  61. to build identical copies of the hash table. This may be inefficient
  62. if the hash table is large or the plan is expensive. In a
  63. <span class="emphasis"><em>parallel hash join</em></span>, the inner side is a
  64. <span class="emphasis"><em>parallel hash</em></span> that divides the work of building
  65. a shared hash table over the cooperating processes.
  66. </p></li></ul></div></div><div class="sect2" id="PARALLEL-AGGREGATION"><div class="titlepage"><div><div><h3 class="title">15.3.3. Parallel Aggregation</h3></div></div></div><p>
  67. <span class="productname">PostgreSQL</span> supports parallel aggregation by aggregating in
  68. two stages. First, each process participating in the parallel portion of
  69. the query performs an aggregation step, producing a partial result for
  70. each group of which that process is aware. This is reflected in the plan
  71. as a <code class="literal">Partial Aggregate</code> node. Second, the partial results are
  72. transferred to the leader via <code class="literal">Gather</code> or <code class="literal">Gather
  73. Merge</code>. Finally, the leader re-aggregates the results across all
  74. workers in order to produce the final result. This is reflected in the
  75. plan as a <code class="literal">Finalize Aggregate</code> node.
  76. </p><p>
  77. Because the <code class="literal">Finalize Aggregate</code> node runs on the leader
  78. process, queries which produce a relatively large number of groups in
  79. comparison to the number of input rows will appear less favorable to the
  80. query planner. For example, in the worst-case scenario the number of
  81. groups seen by the <code class="literal">Finalize Aggregate</code> node could be as many as
  82. the number of input rows which were seen by all worker processes in the
  83. <code class="literal">Partial Aggregate</code> stage. For such cases, there is clearly
  84. going to be no performance benefit to using parallel aggregation. The
  85. query planner takes this into account during the planning process and is
  86. unlikely to choose parallel aggregate in this scenario.
  87. </p><p>
  88. Parallel aggregation is not supported in all situations. Each aggregate
  89. must be <a class="link" href="parallel-safety.html" title="15.4. Parallel Safety">safe</a> for parallelism and must
  90. have a combine function. If the aggregate has a transition state of type
  91. <code class="literal">internal</code>, it must have serialization and deserialization
  92. functions. See <a class="xref" href="sql-createaggregate.html" title="CREATE AGGREGATE"><span class="refentrytitle">CREATE AGGREGATE</span></a> for more details.
  93. Parallel aggregation is not supported if any aggregate function call
  94. contains <code class="literal">DISTINCT</code> or <code class="literal">ORDER BY</code> clause and is also
  95. not supported for ordered set aggregates or when the query involves
  96. <code class="literal">GROUPING SETS</code>. It can only be used when all joins involved in
  97. the query are also part of the parallel portion of the plan.
  98. </p></div><div class="sect2" id="PARALLEL-APPEND"><div class="titlepage"><div><div><h3 class="title">15.3.4. Parallel Append</h3></div></div></div><p>
  99. Whenever <span class="productname">PostgreSQL</span> needs to combine rows
  100. from multiple sources into a single result set, it uses an
  101. <code class="literal">Append</code> or <code class="literal">MergeAppend</code> plan node.
  102. This commonly happens when implementing <code class="literal">UNION ALL</code> or
  103. when scanning a partitioned table. Such nodes can be used in parallel
  104. plans just as they can in any other plan. However, in a parallel plan,
  105. the planner may instead use a <code class="literal">Parallel Append</code> node.
  106. </p><p>
  107. When an <code class="literal">Append</code> node is used in a parallel plan, each
  108. process will execute the child plans in the order in which they appear,
  109. so that all participating processes cooperate to execute the first child
  110. plan until it is complete and then move to the second plan at around the
  111. same time. When a <code class="literal">Parallel Append</code> is used instead, the
  112. executor will instead spread out the participating processes as evenly as
  113. possible across its child plans, so that multiple child plans are executed
  114. simultaneously. This avoids contention, and also avoids paying the startup
  115. cost of a child plan in those processes that never execute it.
  116. </p><p>
  117. Also, unlike a regular <code class="literal">Append</code> node, which can only have
  118. partial children when used within a parallel plan, a <code class="literal">Parallel
  119. Append</code> node can have both partial and non-partial child plans.
  120. Non-partial children will be scanned by only a single process, since
  121. scanning them more than once would produce duplicate results. Plans that
  122. involve appending multiple results sets can therefore achieve
  123. coarse-grained parallelism even when efficient partial plans are not
  124. available. For example, consider a query against a partitioned table
  125. which can only be implemented efficiently by using an index that does
  126. not support parallel scans. The planner might choose a <code class="literal">Parallel
  127. Append</code> of regular <code class="literal">Index Scan</code> plans; each
  128. individual index scan would have to be executed to completion by a single
  129. process, but different scans could be performed at the same time by
  130. different processes.
  131. </p><p>
  132. <a class="xref" href="runtime-config-query.html#GUC-ENABLE-PARALLEL-APPEND">enable_parallel_append</a> can be used to disable
  133. this feature.
  134. </p></div><div class="sect2" id="PARALLEL-PLAN-TIPS"><div class="titlepage"><div><div><h3 class="title">15.3.5. Parallel Plan Tips</h3></div></div></div><p>
  135. If a query that is expected to do so does not produce a parallel plan,
  136. you can try reducing <a class="xref" href="runtime-config-query.html#GUC-PARALLEL-SETUP-COST">parallel_setup_cost</a> or
  137. <a class="xref" href="runtime-config-query.html#GUC-PARALLEL-TUPLE-COST">parallel_tuple_cost</a>. Of course, this plan may turn
  138. out to be slower than the serial plan which the planner preferred, but
  139. this will not always be the case. If you don't get a parallel
  140. plan even with very small values of these settings (e.g. after setting
  141. them both to zero), there may be some reason why the query planner is
  142. unable to generate a parallel plan for your query. See
  143. <a class="xref" href="when-can-parallel-query-be-used.html" title="15.2. When Can Parallel Query Be Used?">Section 15.2</a> and
  144. <a class="xref" href="parallel-safety.html" title="15.4. Parallel Safety">Section 15.4</a> for information on why this may be
  145. the case.
  146. </p><p>
  147. When executing a parallel plan, you can use <code class="literal">EXPLAIN (ANALYZE,
  148. VERBOSE)</code> to display per-worker statistics for each plan node.
  149. This may be useful in determining whether the work is being evenly
  150. distributed between all plan nodes and more generally in understanding the
  151. performance characteristics of the plan.
  152. </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="when-can-parallel-query-be-used.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="parallel-query.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="parallel-safety.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">15.2. When Can Parallel Query Be Used? </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 15.4. Parallel Safety</td></tr></table></div></body></html>
上海开阖软件有限公司 沪ICP备12045867号-1