{"Entry":{"collection":"plan","key":"result","name":"Result","aliases":["Result","T_Result"],"metadata":{"aliases":["Result","T_Result"],"category":"Control","content_hash":"ba1369f2eea4bc89b903d520cbdc0c9b39941b421e72e6dcaf36b2f144de8b8d","derived_content_hash":"db9463b787c6a9fafef7ae46192b1b1671ff4f25cd1aee11c876e1e773a40192","imported_at":"2026-09-30T00:40:44.097532+08:00","name":"Result","name_zh":"Result","slug":"result","summary":"Evaluates a projection and an optional one-time condition, with or without an input plan."}},"Definition":{"Collection":"plan","Key":"result","SourceDatabase":"center","Version":"18","SourceTable":"plan_node","SourceKey":"result","SourceRevision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","Facts":{"comparison_data":{"initializer":"ExecInitResult","memory_mechanism":"unclassified","node_tag":"T_Result","parallel_callbacks":[],"partial_modes":[],"strategies":[],"text_names":["Result"]},"comparison_hash":"7d9e21f5e91321228505ba502e7faa5b9ebdda5ba4d71b8a9b97571a1f87b5f5","description":["Evaluates a projection and an optional one-time condition, with or without an input plan."],"description_zh":"执行投影与可选的一次性条件判断，可以有也可以没有子计划。","description_zh_html":"\u003cp\u003e执行投影与可选的一次性条件判断，可以有也可以没有子计划。\u003c/p\u003e\u003cp\u003e核心节点标识：\u003ccode\u003eT_Result\u003c/code\u003e；EXPLAIN 名称：\u003ccode\u003eResult\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e本版本源码中的并行执行或观测回调：该节点实现中未提取到此类回调。回调的存在不表示该节点必然支持共享并行扫描；在并行工作进程中执行也不等于具有并行感知能力。\u003c/p\u003e\u003ch3\u003e同版本中文手册节选\u003c/h3\u003e\u003cp\u003e\n    查询计划的结构是一棵由\u003cem class=\"firstterm\"\u003e计划节点\u003c/em\u003e组成的树。树的最底层是扫描节点，它们从表中返回原始行。不同的表访问方法对应不同类型的扫描节点，例如顺序扫描、索引扫描和位图索引扫描。也有一些并非表的行来源，例如 \u003ccode class=\"literal\"\u003eVALUES\u003c/code\u003e 子句和 \u003ccode class=\"literal\"\u003eFROM\u003c/code\u003e 中的返回集合函数，它们也各自有对应的扫描节点类型。如果查询需要对原始行执行连接、聚合、排序或其他操作，那么扫描节点之上还会出现额外的节点来完成这些操作。同样，这些操作通常不止一种实现方式，因此这里也会出现不同的节点类型。\u003ccode class=\"command\"\u003eEXPLAIN\u003c/code\u003e 会为计划树中的每个节点输出一行，显示基本节点类型以及规划器对该计划节点执行代价的估计值。还可能出现相对节点摘要行缩进的附加行，用来显示该节点的更多属性。第一行，也就是最顶层节点的摘要行，给出了整个计划的估计总执行代价；规划器力图最小化的正是这个数字。\n   \u003c/p\u003e\u003cp\u003e\n    下面是一个简单的示例，仅用于展示输出的样子：\n\n\u003c/p\u003e\u003cp\u003e\n    由于这个查询没有 \u003ccode class=\"literal\"\u003eWHERE\u003c/code\u003e 子句，它必须扫描表中的所有行，因此规划器选择了一个简单的顺序扫描计划。圆括号中的数字从左到右依次表示：\n\n    \u003c/p\u003e\u003cp\u003e\n    这些代价使用由规划器代价参数决定的任意单位来衡量（见\u003ca class=\"xref\" href=\"/zh/docs/18/runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS\"\u003e第 19.7.2 节\u003c/a\u003e）。传统上通常以磁盘页读取作为代价单位；也就是说，惯例上将 \u003ca class=\"xref\" href=\"/zh/docs/18/runtime-config-query.html#GUC-SEQ-PAGE-COST\"\u003eseq_page_cost\u003c/a\u003e 设为 \u003ccode class=\"literal\"\u003e1.0\u003c/code\u003e，其他代价参数都相对它来设定。本节中的示例都使用默认代价参数。\n   \u003c/p\u003e\u003cp\u003e\u003ca href=\"/zh/docs/18/using-explain.html#USING-EXPLAIN-BASICS\"\u003e查看完整中文手册与上下文\u003c/a\u003e。\u003c/p\u003e\u003cp\u003e本页开头的中文说明为 PG.CENTER 对编辑说明的翻译；手册节选保留对应版本中文文档原文。源码信息及手册示例不代表重新进行过运行测试。\u003c/p\u003e","evidence_kind":"source and documentation","explain_names":["Result"],"explain_prefixes":["Parallel","Async"],"facts":[{"label":"Core node tag","value":"T_Result"},{"label":"Structured EXPLAIN Node Type","value":"Result"},{"label":"Inputs","value":"Optional child plan"},{"label":"Output","value":"Projected tuples"},{"label":"Executor initializer","value":"ExecInitResult"},{"label":"Memory mechanism","value":"unclassified"}],"facts_zh":[{"label":"核心节点标签","value":"T_Result"},{"label":"结构化 EXPLAIN 节点类型","value":"Result"},{"label":"输入","value":"可选的子计划"},{"label":"输出","value":"投影后的元组"},{"label":"执行器初始化函数","value":"ExecInitResult"},{"label":"内存机制","value":"unclassified"}],"memory":{"description":"This extraction does not assign a universal memory limit or spill policy to this node. Inspect the same-build implementation and its expressions or provider.","evidence":[{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/backend/executor/nodeResult.c","path":"src/backend/executor/nodeResult.c","sha256":"32410ec3fc47eea05d944207a7abbf25625029ca8480f5eafee927f896578b9b","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"}],"mechanism":"unclassified","source_notes":[]},"node_tag":"T_Result","parallel_callbacks":[],"partial_modes":[],"related":[{"label":"EXPLAIN","url":"/wiki/sql/explain/?v=18"},{"label":"Using EXPLAIN","url":"/docs/18/using-explain.html"},{"label":"Parallel plans","url":"/docs/18/parallel-plans.html"}],"release":{"channel":"stable","label":"18.6","major":"18","ref":"PostgreSQL 18.6 source archive","revision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","source_snapshot_utc":"","source_url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},"runtime_verified":false,"sections":[{"paragraphs":["Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.","Text names recorded by this source: Result.","Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node."],"title":"EXPLAIN names and attributes"},{"paragraphs":["This extraction does not assign a universal memory limit or spill policy to this node. Inspect the same-build implementation and its expressions or provider."],"title":"Memory and temporary storage"},{"paragraphs":["The source callbacks below can coordinate execution or collect worker instrumentation. Their presence is not a blanket claim that this node supports a shared parallel scan or shared state.","Callbacks in this build: none extracted from this node implementation."],"title":"Parallel execution and instrumentation"},{"paragraphs":["The rows value is a little tricky because it is not the number of rows processed or scanned by the plan node, but rather the number emitted by the node. This is often less than the number scanned, as a result of filtering by any WHERE -clause conditions that are being applied at the node. Ideally the top-level rows estimate will approximate the number of rows actually returned, updated, or deleted by the query.","Compared to regular sorts, sorting incrementally allows returning tuples before the entire result set has been sorted, which particularly enables optimizations with LIMIT queries. It may also reduce memory usage and the likelihood of spilling sorts to disk, but it comes at the cost of the increased overhead of splitting the result set into multiple sorting batches.","In this plan, we have a nested-loop join node with two table scans as inputs, or children. The indentation of the node summary lines reflects the plan tree structure. The join's first, or “ outer ” , child is a bitmap scan similar to those we saw before. Its cost and row count are the same as we'd get from SELECT ... WHERE unique1 \u003c 10 because we are applying the WHERE clause unique1 \u003c 10 at that node. The t1.unique2 = t2.unique2 clause is not relevant yet, so it doesn't affect the row count of the outer scan. The nested-loop join node will run its second, or “ inner ” child once for each row obtained from the outer child. Column values from the current outer row can be plugged into the inner scan; here, the t1.unique2 value from the outer row is available, so we get a plan and costs similar to what we saw above for a simple SELECT ... WHERE t2.unique2 = constant case. (The estimated cost is actually a bit lower than what was seen above, as a result of caching that's expected to occur during the repeated index scans on t2 .) The costs of the loop node are then set on the basis of the cost of the outer scan, plus one repetition of the inner scan for each outer row (10 * 7.90, here), plus a little CPU time for join processing.","This rather artificial example serves to illustrate a couple of points: values from the outer plan level can be passed down into a subplan (here, t.four is passed down) and the results of the sub-select are available to the outer plan. Those result values are shown by EXPLAIN with notations like ( subplan_name ).col N , which refers to the N 'th output column of the sub- SELECT .","It is possible to check the accuracy of the planner's estimates by using EXPLAIN 's ANALYZE option. With this option, EXPLAIN actually executes the query, and then displays the true row counts and true run time accumulated within each plan node, along with the same estimates that a plain EXPLAIN shows. For example, we might get a result like this:","Because each worker executes the parallel portion of the plan to completion, it is not possible to simply take an ordinary query plan and run it using multiple workers. Each worker would produce a full copy of the output result set, so the query would not run any faster than normal but would produce incorrect results. Instead, the parallel portion of the plan must be what is known internally to the query optimizer as a partial plan ; that is, it must be constructed so that each process that executes the plan will generate only a subset of the output rows in such a way that each required output row is guaranteed to be generated by exactly one of the cooperating processes. Generally, this means that the scan on the driving table of the query must be a parallel-aware scan."],"title":"Same-version manual discussion"},{"blocks":[{"code":"EXPLAIN VERBOSE SELECT unique1\nFROM tenk1 t1 WHERE t1.ten = (SELECT (random() * 10)::integer);\n\n                             QUERY PLAN\n--------------------------------------------------------------------\n Seq Scan on public.tenk1 t1  (cost=0.02..470.02 rows=1000 width=4)\n   Output: t1.unique1\n   Filter: (t1.ten = (InitPlan 1).col1)\n   InitPlan 1\n     -\u003e  Result  (cost=0.00..0.02 rows=1 width=4)\n           Output: ((random() * '10'::double precision))::integer","paragraphs":["Example copied from the PostgreSQL 18.6 manual; it was not executed for this collection.","If, in addition to not referencing any variables of the outer query, the sub- SELECT cannot return more than one row, it may instead be implemented as an initplan :"],"source":{"label":"PostgreSQL 18.6 · using-explain","path":"using-explain.html","sha256":"60040c30180093418a0affe56dd27dff9df2504b705b38039589e458bf5c31ed","url":"/docs/18/using-explain.html#USING-EXPLAIN-BASICS"}}],"title":"Examples from this manual build"},{"paragraphs":["nodeResult.c support for constant nodes needing special code.","Result nodes are used in queries where no relations are scanned. Examples of such queries are:","(Remember that in an INSERT or UPDATE, we need a plan tree that generates the new rows.)","Result nodes are also used to optimise queries with constant qualifications (ie, quals that do not depend on the scanned data), such as:","At runtime, the Result node evaluates the constant qual once, which is shown by EXPLAIN as a One-Time Filter. If it's false, we can return an empty result set without running the controlled plan at all. If it's true, we run the controlled plan normally and pass back the results."],"title":"Executor implementation notes"},{"code":"case T_Result:\n\t\t\tpname = sname = \"Result\";\n\t\t\tbreak;","title":"EXPLAIN identity in core source"}],"sections_zh":[{"paragraphs":["结构化格式使用上述 Node Type。文本格式名称还可能包含操作、策略、连接类型、扫描方向或聚合阶段属性。","此源码记录的文本名称：Result.","并行感知与并行安全是不同的计划属性。在并行工作进程内运行的节点不一定是并行感知节点。"],"title":"EXPLAIN 名称与属性"},{"paragraphs":["本次抽取不为此节点设定统一的内存上限或落盘策略。请查看同一构建的实现、相关表达式或提供方。"],"title":"内存与临时存储"},{"paragraphs":["以下源码回调可以协调执行或收集工作进程的测量数据。回调存在不代表该节点普遍支持共享并行扫描或共享状态。","此构建的回调：none extracted from this node implementation."],"title":"并行执行与运行信息采集"},{"paragraphs":["rows 容易令人误解：它表示节点输出的行数，而不是处理或扫描的行数。节点应用 WHERE 条件筛选后，输出行数通常小于扫描行数。理想情况下，顶层 rows 估计应接近查询实际返回、更新或删除的行数。","与普通排序相比，增量排序可在整个结果集尚未排完时就返回元组，尤其有利于优化带 LIMIT 的查询。它还可能减少内存用量和排序溢写磁盘的概率，但代价是将结果集拆成多个排序批次所带来的额外开销。","在这个计划中，有一个嵌套循环连接节点，它的两个输入，也就是两个子节点，都是表扫描。节点摘要行的缩进反映了计划树结构。连接的第一个子节点，也就是 “ 外侧 ” 子节点，是一个与前面见过的位图扫描类似的节点。它的代价和行计数与 SELECT ... WHERE unique1 \u003c 10 得到的结果相同，因为 WHERE 子句 unique1 \u003c 10 正是在该节点上应用的。 t1.unique2 = t2.unique2 子句此时还无关，因此不会影响外侧扫描的行计数。嵌套循环连接节点会对从外侧子节点得到的每一行执行一次第二个，也就是 “ 内侧 ” 子节点。当前外侧行中的列值可以代入内侧扫描；这里外侧行的 t1.unique2 值可用，因此得到的计划和代价与前面看到的简单 SELECT ... WHERE t2.unique2 = constant 情形类似。（由于预期在对 t2 反复执行索引扫描期间会发生缓存命中，估计代价实际上比前面看到的略低一些。）随后，循环节点的代价建立在外侧扫描代价之上，再加上每个外侧行都要执行一次内侧扫描的代价（这里是 10 * 7.90），以及少量连接处理的 CPU 时间。","这个刻意构造的示例说明了两点：外层计划的值可传入子计划（这里传入 t.four），子查询结果也可供外层计划使用。EXPLAIN 用 (subplan_name).col N 一类记号显示这些结果值，表示子 SELECT 的第 N 个输出列。","可使用 EXPLAIN 的 ANALYZE 选项检查规划器估算是否准确。使用此选项时，EXPLAIN 会实际执行查询，然后显示每个计划节点累计的真实行数和真实运行时间，以及普通 EXPLAIN 所显示的估算值。例如，可能得到如下结果：","由于每个工作进程都会将计划的并行部分执行到底，因此不能简单地拿一个普通查询计划并让多个工作进程同时运行。那样每个工作进程都会生成完整输出结果集的一份副本，所以查询不仅不会比平常更快，反而会产生错误结果。相反，计划的并行部分必须是查询优化器内部所说的 部分计划 ；也就是说，它必须被构造为使执行该计划的每个进程只生成输出行的一个子集，并且保证每一条所需输出行都恰好由某个协作进程生成一次。一般来说，这意味着查询驱动表上的扫描必须是并行感知扫描。"],"title":"同版本手册说明"},{"blocks":[{"code":"EXPLAIN VERBOSE SELECT unique1\nFROM tenk1 t1 WHERE t1.ten = (SELECT (random() * 10)::integer);\n\n                             QUERY PLAN\n--------------------------------------------------------------------\n Seq Scan on public.tenk1 t1  (cost=0.02..470.02 rows=1000 width=4)\n   Output: t1.unique1\n   Filter: (t1.ten = (InitPlan 1).col1)\n   InitPlan 1\n     -\u003e  Result  (cost=0.00..0.02 rows=1 width=4)\n           Output: ((random() * '10'::double precision))::integer","paragraphs":["示例摘自 PostgreSQL 18.6 手册；本百科未实际执行此示例。","如果子 SELECT 不仅不引用外层查询的任何变量，而且最多只会返回一行，那么它还可能被实现成一个 初始计划 ："],"source":{"label":"PostgreSQL 18.6 · using-explain","path":"using-explain.html","sha256":"60040c30180093418a0affe56dd27dff9df2504b705b38039589e458bf5c31ed","url":"/docs/18/using-explain.html#USING-EXPLAIN-BASICS"}}],"title":"本版手册中的示例"},{"paragraphs":["nodeResult.c：支持需要特殊代码的常量节点。","Result 节点用于不扫描任何关系的查询，例如：","（请记住，INSERT 或 UPDATE 需要一棵生成新行的计划树。）","Result 节点也用于优化带有常量条件（即不依赖扫描数据的条件）的查询，例如：","运行时，Result 节点只计算一次常量条件，EXPLAIN 将其显示为 One-Time Filter。如果条件为假，无需运行受控计划便可返回空结果集；如果为真，则正常运行受控计划并传回结果。"],"title":"执行器实现说明"},{"code":"case T_Result:\n\t\t\tpname = sname = \"Result\";\n\t\t\tbreak;","title":"核心源码中的 EXPLAIN 标识"}],"source_inventory":{"executor":"src/backend/executor/execProcnode.c","explain":"src/backend/commands/explain.c","implementation":"src/backend/executor/nodeResult.c"},"sources":[{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/backend/commands/explain.c:1379","line":1379,"path":"src/backend/commands/explain.c","sha256":"34c86d6070224a0e981efef51f79101d6d505e5874f1684ace183034bab14bb4","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/backend/executor/execProcnode.c:166","line":166,"path":"src/backend/executor/execProcnode.c","sha256":"f8a06a3f539077249b20664b2812433db6d7bd12b2c0ca633525db43d06f112a","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/backend/executor/nodeResult.c","path":"src/backend/executor/nodeResult.c","sha256":"32410ec3fc47eea05d944207a7abbf25625029ca8480f5eafee927f896578b9b","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/include/nodes/plannodes.h","path":"src/include/nodes/plannodes.h","sha256":"52422b327a8049fbbb20d8b96008a0fc0a6fafa60f7eff3c695d5b2e83830120","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"label":"PostgreSQL 18.6 · using-explain","path":"using-explain.html","sha256":"60040c30180093418a0affe56dd27dff9df2504b705b38039589e458bf5c31ed","url":"/docs/18/using-explain.html#USING-EXPLAIN-BASICS"},{"label":"PostgreSQL 18.6 · using-explain","path":"using-explain.html","sha256":"60040c30180093418a0affe56dd27dff9df2504b705b38039589e458bf5c31ed","url":"/docs/18/using-explain.html#USING-EXPLAIN-ANALYZE"},{"label":"PostgreSQL 18.6 · parallel-plans","path":"parallel-plans.html","sha256":"62207d207bead82b01b59dc119c4f95856f08655cc11d4699a05a40867ed2070","url":"/docs/18/parallel-plans.html#PARALLEL-PLANS"}],"strategies":[],"tables":[{"columns":[{"key":"label","label":"Text-format label"},{"key":"identity","label":"Structured node identity"}],"key":"explain-labels","rows":[{"identity":"Result","label":"Result"}],"title":"EXPLAIN labels in this source build"}],"tables_zh":[{"columns":[{"key":"label","label":"文本格式标签"},{"key":"identity","label":"结构化节点标识"}],"key":"explain-labels","rows":[{"identity":"Result","label":"Result"}],"title":"本构建中的 EXPLAIN 标签"}],"zh_from":{"authored_translation":"authored-translation-of-reviewed-guidance","body_sha256":"7167ebc3a0b2071db31f36cf67c9b265819341c3bc316db3d3a0ea8d7bcfc1bc","kind":"same-version-chinese-manual-with-authored-translation-of-reviewed-guidance","manual":{"anchor":"USING-EXPLAIN-BASICS","build_id":107,"extraction":"concept-introduction","fragment_sha256":"bc79b6f9c70f2b56968e08ea26d2c9ec3d395e425aca0594e227203daa0ad29b","locale":"zh-Hans","page_key":"using-explain.html","source_hash":"d2f749744b3ac5aa2eb0154f295e8163903cd20fcc130c74c6172cdf2ae3a9df","source_revision":"unknown:rendered-translation-baseline","translated_from_revision":null,"translation_revision":"git:b1b500221dbe5437cfca004d6b04d3f6e422765d;html-sha256:08e987a66af27b98444a8057c256314eafa13611a3fb9e888214fc436824244b","url":"/zh/docs/18/using-explain.html#USING-EXPLAIN-BASICS","version":"18"},"runtime_rerun":false,"source_facts_revision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}},"ManualEvidence":{"release":{"channel":"stable","label":"18.6","major":"18","ref":"PostgreSQL 18.6 source archive","revision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","source_snapshot_utc":"","source_url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},"sources":[{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/backend/commands/explain.c:1379","line":1379,"path":"src/backend/commands/explain.c","sha256":"34c86d6070224a0e981efef51f79101d6d505e5874f1684ace183034bab14bb4","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/backend/executor/execProcnode.c:166","line":166,"path":"src/backend/executor/execProcnode.c","sha256":"f8a06a3f539077249b20664b2812433db6d7bd12b2c0ca633525db43d06f112a","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/backend/executor/nodeResult.c","path":"src/backend/executor/nodeResult.c","sha256":"32410ec3fc47eea05d944207a7abbf25625029ca8480f5eafee927f896578b9b","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/include/nodes/plannodes.h","path":"src/include/nodes/plannodes.h","sha256":"52422b327a8049fbbb20d8b96008a0fc0a6fafa60f7eff3c695d5b2e83830120","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"label":"PostgreSQL 18.6 · using-explain","path":"using-explain.html","sha256":"60040c30180093418a0affe56dd27dff9df2504b705b38039589e458bf5c31ed","url":"/docs/18/using-explain.html#USING-EXPLAIN-BASICS"},{"label":"PostgreSQL 18.6 · using-explain","path":"using-explain.html","sha256":"60040c30180093418a0affe56dd27dff9df2504b705b38039589e458bf5c31ed","url":"/docs/18/using-explain.html#USING-EXPLAIN-ANALYZE"},{"label":"PostgreSQL 18.6 · parallel-plans","path":"parallel-plans.html","sha256":"62207d207bead82b01b59dc119c4f95856f08655cc11d4699a05a40867ed2070","url":"/docs/18/parallel-plans.html#PARALLEL-PLANS"}]},"MeasuredEvidence":{"runtime_verified":false}},"Text":{"Collection":"plan","Key":"result","SourceDatabase":"center","Version":"18","Locale":"en","Title":"Result","Summary":"Evaluates a projection and an optional one-time condition, with or without an input plan.","BodyHTML":"\u003cp\u003eEvaluates a projection and an optional one-time condition, with or without an input plan.\u003c/p\u003e","SourceRevision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","ContentHash":"d0efc2ca8d7ffa76a053bd218d90f5de608fb1f0fdc0c8a468a9321a03f6a410","Payload":{"description":["Evaluates a projection and an optional one-time condition, with or without an input plan."],"related":[{"label":"EXPLAIN","url":"/wiki/sql/explain/?v=18"},{"label":"Using EXPLAIN","url":"/docs/18/using-explain.html"},{"label":"Parallel plans","url":"/docs/18/parallel-plans.html"}],"sections":[{"paragraphs":["Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.","Text names recorded by this source: Result.","Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node."],"title":"EXPLAIN names and attributes"},{"paragraphs":["This extraction does not assign a universal memory limit or spill policy to this node. Inspect the same-build implementation and its expressions or provider."],"title":"Memory and temporary storage"},{"paragraphs":["The source callbacks below can coordinate execution or collect worker instrumentation. Their presence is not a blanket claim that this node supports a shared parallel scan or shared state.","Callbacks in this build: none extracted from this node implementation."],"title":"Parallel execution and instrumentation"},{"paragraphs":["The rows value is a little tricky because it is not the number of rows processed or scanned by the plan node, but rather the number emitted by the node. This is often less than the number scanned, as a result of filtering by any WHERE -clause conditions that are being applied at the node. Ideally the top-level rows estimate will approximate the number of rows actually returned, updated, or deleted by the query.","Compared to regular sorts, sorting incrementally allows returning tuples before the entire result set has been sorted, which particularly enables optimizations with LIMIT queries. It may also reduce memory usage and the likelihood of spilling sorts to disk, but it comes at the cost of the increased overhead of splitting the result set into multiple sorting batches.","In this plan, we have a nested-loop join node with two table scans as inputs, or children. The indentation of the node summary lines reflects the plan tree structure. The join's first, or “ outer ” , child is a bitmap scan similar to those we saw before. Its cost and row count are the same as we'd get from SELECT ... WHERE unique1 \u003c 10 because we are applying the WHERE clause unique1 \u003c 10 at that node. The t1.unique2 = t2.unique2 clause is not relevant yet, so it doesn't affect the row count of the outer scan. The nested-loop join node will run its second, or “ inner ” child once for each row obtained from the outer child. Column values from the current outer row can be plugged into the inner scan; here, the t1.unique2 value from the outer row is available, so we get a plan and costs similar to what we saw above for a simple SELECT ... WHERE t2.unique2 = constant case. (The estimated cost is actually a bit lower than what was seen above, as a result of caching that's expected to occur during the repeated index scans on t2 .) The costs of the loop node are then set on the basis of the cost of the outer scan, plus one repetition of the inner scan for each outer row (10 * 7.90, here), plus a little CPU time for join processing.","This rather artificial example serves to illustrate a couple of points: values from the outer plan level can be passed down into a subplan (here, t.four is passed down) and the results of the sub-select are available to the outer plan. Those result values are shown by EXPLAIN with notations like ( subplan_name ).col N , which refers to the N 'th output column of the sub- SELECT .","It is possible to check the accuracy of the planner's estimates by using EXPLAIN 's ANALYZE option. With this option, EXPLAIN actually executes the query, and then displays the true row counts and true run time accumulated within each plan node, along with the same estimates that a plain EXPLAIN shows. For example, we might get a result like this:","Because each worker executes the parallel portion of the plan to completion, it is not possible to simply take an ordinary query plan and run it using multiple workers. Each worker would produce a full copy of the output result set, so the query would not run any faster than normal but would produce incorrect results. Instead, the parallel portion of the plan must be what is known internally to the query optimizer as a partial plan ; that is, it must be constructed so that each process that executes the plan will generate only a subset of the output rows in such a way that each required output row is guaranteed to be generated by exactly one of the cooperating processes. Generally, this means that the scan on the driving table of the query must be a parallel-aware scan."],"title":"Same-version manual discussion"},{"blocks":[{"code":"EXPLAIN VERBOSE SELECT unique1\nFROM tenk1 t1 WHERE t1.ten = (SELECT (random() * 10)::integer);\n\n                             QUERY PLAN\n--------------------------------------------------------------------\n Seq Scan on public.tenk1 t1  (cost=0.02..470.02 rows=1000 width=4)\n   Output: t1.unique1\n   Filter: (t1.ten = (InitPlan 1).col1)\n   InitPlan 1\n     -\u003e  Result  (cost=0.00..0.02 rows=1 width=4)\n           Output: ((random() * '10'::double precision))::integer","paragraphs":["Example copied from the PostgreSQL 18.6 manual; it was not executed for this collection.","If, in addition to not referencing any variables of the outer query, the sub- SELECT cannot return more than one row, it may instead be implemented as an initplan :"],"source":{"label":"PostgreSQL 18.6 · using-explain","path":"using-explain.html","sha256":"60040c30180093418a0affe56dd27dff9df2504b705b38039589e458bf5c31ed","url":"/docs/18/using-explain.html#USING-EXPLAIN-BASICS"}}],"title":"Examples from this manual build"},{"paragraphs":["nodeResult.c support for constant nodes needing special code.","Result nodes are used in queries where no relations are scanned. Examples of such queries are:","(Remember that in an INSERT or UPDATE, we need a plan tree that generates the new rows.)","Result nodes are also used to optimise queries with constant qualifications (ie, quals that do not depend on the scanned data), such as:","At runtime, the Result node evaluates the constant qual once, which is shown by EXPLAIN as a One-Time Filter. If it's false, we can return an empty result set without running the controlled plan at all. If it's true, we run the controlled plan normally and pass back the results."],"title":"Executor implementation notes"},{"code":"case T_Result:\n\t\t\tpname = sname = \"Result\";\n\t\t\tbreak;","title":"EXPLAIN identity in core source"}],"tables":[{"columns":[{"key":"label","label":"Text-format label"},{"key":"identity","label":"Structured node identity"}],"key":"explain-labels","rows":[{"identity":"Result","label":"Result"}],"title":"EXPLAIN labels in this source build"}]}},"RequestedLocale":"en","Fallback":false,"Versions":["10","11","12","13","14","15","16","17","18","19","20"],"Locales":["en","zh-Hans"],"Signatures":null,"Spellings":null,"SQLState":null,"Evidence":null}
