{"kind": "plan", "major": "18", "item": {"slug": "append", "name": "Append", "name_zh": "Append", "category": "\u7ec4\u5408", "summary": "\u904d\u5386\u5404\u5b50\u8ba1\u5212\u5e76\u5408\u5e76\u5176\u8f93\u51fa\u884c\u3002", "aliases": ["Append", "T_Append"], "content_hash": "bda7fdd66ebae4ebb964e96fb7f3d904105ce876c1866e1eb8410cf83f208c88", "versions": {"10": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_Append"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "Append"}, {"label": "\u8f93\u5165", "value": "\u591a\u4e2a\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5408\u5e76\u540e\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitAppend"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "unclassified"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "e473b524e0fcf76ce36a21e33241f9f187deeacc3c57746e7beddb6d945f78e4", "archive_sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9"}], "mechanism": "unclassified", "description": "\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002", "source_notes": []}, "tables": [{"key": "explain-labels", "rows": [{"label": "Append", "identity": "Append"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=10", "label": "EXPLAIN"}, {"url": "/docs/10/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/10/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}], "release": {"ref": "PostgreSQL 10.23 source archive", "label": "10.23", "major": "10", "channel": "historical", "revision": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9", "source_url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "line": 906, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:906", "sha256": "a785298532047cfeda969e78c3597a343dc1c56d61ba85830b0f16a02a14b5a1", "archive_sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9"}, {"url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "line": 179, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:179", "sha256": "cea76648bb38ae55f18f989768bee1a4ee025691ceea0f86bccb29dcdc166acc", "archive_sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9"}, {"url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "e473b524e0fcf76ce36a21e33241f9f187deeacc3c57746e7beddb6d945f78e4", "archive_sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9"}, {"url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "d562c321108844798cd234303fffb618f13d4ee3f3a5ac79bfd963b077e47c22", "archive_sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9"}], "node_tag": "T_Append", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aAppend.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1anone extracted from this node implementation."]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["\u8bf4\u660e\uff1a\u6bcf\u4e2a Append \u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5fc5\u987b\u9010\u4e00\u5904\u7406\u7684\u5b50\u8ba1\u5212\uff0c\u65b9\u5411\u53ef\u4ee5\u6b63\u5411\u6216\u53cd\u5411\u3002\u6267\u884c\u7b2c whichplan \u4e2a\u5b50\u8ba1\u5212\u53d6\u56de\u5143\u7ec4\uff0c\u76f4\u5230\u5b83\u4e0d\u518d\u8fd4\u56de\u5143\u7ec4\uff0c\u7136\u540e\u5173\u95ed\u8be5\u8ba1\u5212\u5e76\u542f\u52a8\u4e0b\u4e00\u4e2a\u3002", "Append \u8282\u70b9\u4e0d\u4f7f\u7528\u5de6\u3001\u53f3\u5b50\u6811\uff0c\u800c\u662f\u7ef4\u62a4\u4e00\u4e2a\u5b50\u8ba1\u5212\u5217\u8868\uff0c\u56e0\u6b64\u5178\u578b\u7684 Append \u8282\u70b9\u5728\u8ba1\u5212\u6811\u4e2d\u5982\u4e0b\u6240\u793a\uff1a", "... / Append -------+------+------+--- nil / \\ | | | nil nil ... ... ... subplans", "Append \u8282\u70b9\u76ee\u524d\u7528\u4e8e\u5e76\u96c6\u64cd\u4f5c\uff0c\u4e5f\u7528\u4e8e\u9700\u8981\u626b\u63cf\u591a\u4e2a\u5173\u7cfb\u7684\u7ee7\u627f\u67e5\u8be2\u3002\u4f8b\u5982\uff0c\u5728\u6807\u51c6\u7684 person/student/employee/student-emp \u793a\u4f8b\u4e2d\uff0cstudent \u548c employee \u7ee7\u627f\u81ea person\uff0c\u800c student-emp \u540c\u65f6\u7ee7\u627f\u81ea student \u548c employee\uff0c\u67e5\u8be2\u5982\u4e0b\uff1a", "| Append -------+-------+--------+--------+ / \\ | | | | nil nil Scan Scan Scan Scan | | | | person employee student student-emp"]}, {"code": "case T_Append:\n\t\t\tpname = sname = \"Append\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u904d\u5386\u5404\u5b50\u8ba1\u5212\u5e76\u5408\u5e76\u5176\u8f93\u51fa\u884c\u3002"], "localization": {"status": "complete", "sources": [], "language": "zh", "original_text": {"/versions/10/description/0": "Visits its child plans and combines their rows.", "/versions/10/facts/0/label": "Core node tag", "/versions/10/facts/1/label": "Structured EXPLAIN Node Type", "/versions/10/facts/2/label": "Inputs", "/versions/10/facts/2/value": "Multiple child plans", "/versions/10/facts/3/label": "Output", "/versions/10/facts/3/value": "Combined tuples", "/versions/10/facts/4/label": "Executor initializer", "/versions/10/facts/5/label": "Memory mechanism", "/versions/10/tables/0/title": "EXPLAIN labels in this source build", "/versions/10/related/1/label": "Using EXPLAIN", "/versions/10/related/2/label": "Parallel plans", "/versions/10/sections/0/title": "EXPLAIN names and attributes", "/versions/10/sections/1/title": "Memory and temporary storage", "/versions/10/sections/2/title": "Parallel execution and instrumentation", "/versions/10/sections/3/title": "Executor implementation notes", "/versions/10/sections/4/title": "EXPLAIN identity in core source", "/versions/10/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.", "/versions/10/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/10/sections/0/paragraphs/1": "Text names recorded by this source: Append.", "/versions/10/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/10/sections/1/paragraphs/0": "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.", "/versions/10/sections/2/paragraphs/0": "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.", "/versions/10/sections/2/paragraphs/1": "Callbacks in this build: none extracted from this node implementation.", "/versions/10/sections/3/paragraphs/0": "NOTES Each append node contains a list of one or more subplans which must be iteratively processed (forwards or backwards). Tuples are retrieved by executing the 'whichplan'th subplan until the subplan stops returning tuples, at which point that plan is shut down and the next started up.", "/versions/10/sections/3/paragraphs/1": "Append nodes don't make use of their left and right subtrees, rather they maintain a list of subplans so a typical append node looks like this in the plan tree:", "/versions/10/sections/3/paragraphs/3": "Append nodes are currently used for unions, and to support inheritance queries, where several relations need to be scanned. For example, in our standard person/student/employee/student-emp example, where student and employee inherit from person and student-emp inherits from student and employee, the query:", "/versions/10/tables/0/columns/0/label": "Text-format label", "/versions/10/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "cfa3830dc879d583951493e9aad88ed88f5beaa86e17f6d2b936e3ca54744172"}, "evidence_kind": "source and documentation", "explain_names": ["Append"], "partial_modes": [], "comparison_data": {"node_tag": "T_Append", "strategies": [], "text_names": ["Append"], "initializer": "ExecInitAppend", "partial_modes": [], "memory_mechanism": "unclassified", "parallel_callbacks": []}, "comparison_hash": "494c616cd0c3db8cfa872d05ac27ead20a9d237ba53a6bf8893491043fe7a7be", "explain_prefixes": ["Parallel"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeAppend.c"}, "parallel_callbacks": []}, "11": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_Append"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "Append"}, {"label": "\u8f93\u5165", "value": "\u591a\u4e2a\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5408\u5e76\u540e\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitAppend"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "unclassified"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "249841abf0d545d27a149cbcce2faeef6070a2bc78fa06a9e00eb100b275ec27", "archive_sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0"}], "mechanism": "unclassified", "description": "\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002", "source_notes": []}, "tables": [{"key": "explain-labels", "rows": [{"label": "Append", "identity": "Append"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=11", "label": "EXPLAIN"}, {"url": "/docs/11/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/11/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/enable_parallel_append/?v=11", "label": "enable_parallel_append"}], "release": {"ref": "PostgreSQL 11.22 source archive", "label": "11.22", "major": "11", "channel": "historical", "revision": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0", "source_url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "line": 1031, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1031", "sha256": "9df8400c1a4377179572ceb916d6020fca4e2760f74bf416d77ed97476523bbd", "archive_sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0"}, {"url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "line": 179, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:179", "sha256": "95ef4d4a5df4c29f14af9763fae2c530449bdacdf3853d9ff297adf1fed6153b", "archive_sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0"}, {"url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "249841abf0d545d27a149cbcce2faeef6070a2bc78fa06a9e00eb100b275ec27", "archive_sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0"}, {"url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "5e0511194183800e8d6eb293fd4b40639c7d3118e2d199c8e7865ba4fa4cf67f", "archive_sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0"}, {"url": "https://pg.center/docs/11/using-explain.html#USING-EXPLAIN-CAVEATS", "path": "using-explain.html", "label": "PostgreSQL 11.22 \u00b7 using-explain", "sha256": "8411bc78085d4737e32d7cca103d859da6c6539e33ec5e2fba46e74c6f199d8a", "language": "en", "original_url": "/docs/11/using-explain.html#USING-EXPLAIN-CAVEATS"}, {"url": "https://pg.center/docs/11/parallel-plans.html#PARALLEL-APPEND", "path": "parallel-plans.html", "label": "PostgreSQL 11.22 \u00b7 parallel-plans", "sha256": "353df5869034b7665159a74037d9cf3e1800d15efcea3390daaa99aae89fa288", "language": "en", "original_url": "/docs/11/parallel-plans.html#PARALLEL-APPEND"}], "node_tag": "T_Append", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aAppend.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1aExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM."]}, {"title": "\u540c\u7248\u672c\u624b\u518c\u8bf4\u660e", "paragraphs": ["\u901a\u5e38 EXPLAIN \u663e\u793a\u89c4\u5212\u5668\u521b\u5efa\u7684\u6bcf\u4e2a\u8282\u70b9\u3002\u4f46\u6267\u884c\u5668\u6709\u65f6\u53ef\u4ee5\u6839\u636e\u89c4\u5212\u9636\u6bb5\u5c1a\u4e0d\u53ef\u77e5\u7684\u53c2\u6570\u503c\uff0c\u5224\u5b9a\u67d0\u4e9b\u8282\u70b9\u65e0\u6cd5\u4ea7\u751f\u4efb\u4f55\u884c\uff0c\u56e0\u6b64\u4e0d\u5fc5\u6267\u884c\u3002\uff08\u76ee\u524d\u4ec5\u4f1a\u53d1\u751f\u5728\u626b\u63cf\u5206\u533a\u8868\u7684 Append \u8282\u70b9\u7684\u5b50\u8282\u70b9\u4e0a\u3002\uff09\u6b64\u65f6 EXPLAIN \u7701\u7565\u8fd9\u4e9b\u8282\u70b9\uff0c\u6539\u4e3a\u663e\u793a Subplans Removed: N\u3002", "\u6bcf\u5f53 PostgreSQL \u9700\u8981\u5c06\u6765\u81ea\u591a\u4e2a\u6e90\u7684\u884c\u5408\u5e76\u6210\u4e00\u4e2a\u7ed3\u679c\u96c6\u65f6\uff0c\u5b83\u5c31\u4f1a\u4f7f\u7528 Append \u6216 MergeAppend \u8ba1\u5212\u8282\u70b9\u3002\u8fd9\u79cd\u60c5\u51b5\u5e38\u89c1\u4e8e\u5b9e\u73b0 UNION ALL \u6216\u626b\u63cf\u5206\u533a\u8868\u65f6\u3002\u8fd9\u6837\u7684\u8282\u70b9\u548c\u5176\u4ed6\u4efb\u4f55\u8ba1\u5212\u4e2d\u7684\u60c5\u5f62\u4e00\u6837\uff0c\u4e5f\u53ef\u4ee5\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u3002\u4e0d\u8fc7\uff0c\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\uff0c\u89c4\u5212\u5668\u4e5f\u53ef\u80fd\u6539\u7528 Parallel Append \u8282\u70b9\u3002", "\u5f53 Append \u8282\u70b9\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u65f6\uff0c\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u4f1a\u6309\u7167\u5b50\u8ba1\u5212\u51fa\u73b0\u7684\u987a\u5e8f\u6267\u884c\u5b83\u4eec\uff0c\u56e0\u6b64\u6240\u6709\u53c2\u4e0e\u8fdb\u7a0b\u4f1a\u534f\u4f5c\u6267\u884c\u7b2c\u4e00\u4e2a\u5b50\u8ba1\u5212\u76f4\u5230\u5176\u5b8c\u6210\uff0c\u7136\u540e\u518d\u5927\u81f4\u540c\u65f6\u8f6c\u5411\u7b2c\u4e8c\u4e2a\u5b50\u8ba1\u5212\u3002\u800c\u5f53\u4f7f\u7528 Parallel Append \u65f6\uff0c\u6267\u884c\u5668\u4f1a\u5c3d\u53ef\u80fd\u5747\u5300\u5730\u5c06\u53c2\u4e0e\u8fdb\u7a0b\u5206\u6563\u5230\u5404\u4e2a\u5b50\u8ba1\u5212\u4e0a\uff0c\u4ece\u800c\u4f7f\u591a\u4e2a\u5b50\u8ba1\u5212\u80fd\u591f\u540c\u65f6\u6267\u884c\u3002\u8fd9\u6837\u65e2\u907f\u514d\u4e86\u4e89\u7528\uff0c\u4e5f\u907f\u514d\u8ba9\u90a3\u4e9b\u4ece\u672a\u6267\u884c\u67d0\u4e2a\u5b50\u8ba1\u5212\u7684\u8fdb\u7a0b\u627f\u62c5\u5176\u542f\u52a8\u4ee3\u4ef7\u3002", "\u6b64\u5916\uff0c\u4e0e\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\u53ea\u80fd\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\u7684\u666e\u901a Append \u8282\u70b9\u4e0d\u540c\uff0cParallel Append \u8282\u70b9\u65e2\u53ef\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\uff0c\u4e5f\u53ef\u5305\u542b\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u3002\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u53ea\u7531\u4e00\u4e2a\u8fdb\u7a0b\u626b\u63cf\uff0c\u56e0\u4e3a\u591a\u6b21\u626b\u63cf\u4f1a\u4ea7\u751f\u91cd\u590d\u7ed3\u679c\u3002\u56e0\u6b64\uff0c\u5373\u4f7f\u6ca1\u6709\u9ad8\u6548\u7684\u90e8\u5206\u8ba1\u5212\uff0c\u62fc\u63a5\u591a\u4e2a\u7ed3\u679c\u96c6\u7684\u8ba1\u5212\u4e5f\u80fd\u5b9e\u73b0\u7c97\u7c92\u5ea6\u5e76\u884c\u3002\u4f8b\u5982\uff0c\u9488\u5bf9\u5206\u533a\u8868\u7684\u67e5\u8be2\uff0c\u53ef\u80fd\u53ea\u6709\u501f\u52a9\u4e0d\u652f\u6301\u5e76\u884c\u626b\u63cf\u7684\u7d22\u5f15\u624d\u80fd\u9ad8\u6548\u6267\u884c\u3002\u89c4\u5212\u5668\u53ef\u80fd\u9009\u62e9\u4f7f\u7528 Parallel Append \u62fc\u63a5\u591a\u4e2a\u666e\u901a Index Scan \u8ba1\u5212\uff1b\u6bcf\u6b21\u7d22\u5f15\u626b\u63cf\u90fd\u5fc5\u987b\u7531\u5355\u4e2a\u8fdb\u7a0b\u5b8c\u6574\u6267\u884c\uff0c\u4f46\u4e0d\u540c\u626b\u63cf\u53ef\u4ee5\u7531\u4e0d\u540c\u8fdb\u7a0b\u540c\u65f6\u6267\u884c\u3002"]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["\u8bf4\u660e\uff1a\u6bcf\u4e2a Append \u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5fc5\u987b\u9010\u4e00\u5904\u7406\u7684\u5b50\u8ba1\u5212\uff0c\u65b9\u5411\u53ef\u4ee5\u6b63\u5411\u6216\u53cd\u5411\u3002\u6267\u884c\u7b2c whichplan \u4e2a\u5b50\u8ba1\u5212\u53d6\u56de\u5143\u7ec4\uff0c\u76f4\u5230\u5b83\u4e0d\u518d\u8fd4\u56de\u5143\u7ec4\uff0c\u7136\u540e\u5173\u95ed\u8be5\u8ba1\u5212\u5e76\u542f\u52a8\u4e0b\u4e00\u4e2a\u3002", "Append \u8282\u70b9\u4e0d\u4f7f\u7528\u5de6\u3001\u53f3\u5b50\u6811\uff0c\u800c\u662f\u7ef4\u62a4\u4e00\u4e2a\u5b50\u8ba1\u5212\u5217\u8868\uff0c\u56e0\u6b64\u5178\u578b\u7684 Append \u8282\u70b9\u5728\u8ba1\u5212\u6811\u4e2d\u5982\u4e0b\u6240\u793a\uff1a", "... / Append -------+------+------+--- nil / \\ | | | nil nil ... ... ... subplans", "Append \u8282\u70b9\u76ee\u524d\u7528\u4e8e\u5e76\u96c6\u64cd\u4f5c\uff0c\u4e5f\u7528\u4e8e\u9700\u8981\u626b\u63cf\u591a\u4e2a\u5173\u7cfb\u7684\u7ee7\u627f\u67e5\u8be2\u3002\u4f8b\u5982\uff0c\u5728\u6807\u51c6\u7684 person/student/employee/student-emp \u793a\u4f8b\u4e2d\uff0cstudent \u548c employee \u7ee7\u627f\u81ea person\uff0c\u800c student-emp \u540c\u65f6\u7ee7\u627f\u81ea student \u548c employee\uff0c\u67e5\u8be2\u5982\u4e0b\uff1a", "| Append -------+-------+--------+--------+ / \\ | | | | nil nil Scan Scan Scan Scan | | | | person employee student student-emp"]}, {"code": "case T_Append:\n\t\t\tpname = sname = \"Append\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u904d\u5386\u5404\u5b50\u8ba1\u5212\u5e76\u5408\u5e76\u5176\u8f93\u51fa\u884c\u3002"], "localization": {"status": "complete", "sources": [{"url": "/docs/11/parallel-plans.html", "method": "same-major semantic node", "sha256": "963d71be1a9c27fcc3f5c60b2479c7b94c6d85bfc4e1e20289a1c0e6f284ec85", "language": "zh", "matched_nodes": ["#PARALLEL-PLANS/div[6]/p[1]", "#PARALLEL-PLANS/div[6]/p[2]"]}], "language": "zh", "original_text": {"/versions/11/description/0": "Visits its child plans and combines their rows.", "/versions/11/facts/0/label": "Core node tag", "/versions/11/facts/1/label": "Structured EXPLAIN Node Type", "/versions/11/facts/2/label": "Inputs", "/versions/11/facts/2/value": "Multiple child plans", "/versions/11/facts/3/label": "Output", "/versions/11/facts/3/value": "Combined tuples", "/versions/11/facts/4/label": "Executor initializer", "/versions/11/facts/5/label": "Memory mechanism", "/versions/11/tables/0/title": "EXPLAIN labels in this source build", "/versions/11/related/1/label": "Using EXPLAIN", "/versions/11/related/2/label": "Parallel plans", "/versions/11/sections/0/title": "EXPLAIN names and attributes", "/versions/11/sections/1/title": "Memory and temporary storage", "/versions/11/sections/2/title": "Parallel execution and instrumentation", "/versions/11/sections/3/title": "Same-version manual discussion", "/versions/11/sections/4/title": "Executor implementation notes", "/versions/11/sections/5/title": "EXPLAIN identity in core source", "/versions/11/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.", "/versions/11/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/11/sections/0/paragraphs/1": "Text names recorded by this source: Append.", "/versions/11/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/11/sections/1/paragraphs/0": "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.", "/versions/11/sections/2/paragraphs/0": "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.", "/versions/11/sections/2/paragraphs/1": "Callbacks in this build: ExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM.", "/versions/11/sections/3/paragraphs/0": "Normally, EXPLAIN will display every plan node created by the planner. However, there are cases where the executor can determine that certain nodes need not be executed because they cannot produce any rows, based on parameter values that were not available at planning time. (Currently this can only happen for child nodes of an Append node that is scanning a partitioned table.) When this happens, those plan nodes are omitted from the EXPLAIN output and a Subplans Removed: N annotation appears instead.", "/versions/11/sections/3/paragraphs/1": "Whenever PostgreSQL needs to combine rows from multiple sources into a single result set, it uses an Append or MergeAppend plan node. This commonly happens when implementing UNION ALL or when scanning a partitioned table. Such nodes can be used in parallel plans just as they can in any other plan. However, in a parallel plan, the planner may instead use a Parallel Append node.", "/versions/11/sections/3/paragraphs/2": "When an Append node is used in a parallel plan, each process will execute the child plans in the order in which they appear, so that all participating processes cooperate to execute the first child plan until it is complete and then move to the second plan at around the same time. When a Parallel Append is used instead, the executor will instead spread out the participating processes as evenly as possible across its child plans, so that multiple child plans are executed simultaneously. This avoids contention, and also avoids paying the startup cost of a child plan in those processes that never execute it.", "/versions/11/sections/3/paragraphs/3": "Also, unlike a regular Append node, which can only have partial children when used within a parallel plan, a Parallel Append node can have both partial and non-partial child plans. Non-partial children will be scanned by only a single process, since scanning them more than once would produce duplicate results. Plans that involve appending multiple results sets can therefore achieve coarse-grained parallelism even when efficient partial plans are not available. For example, consider a query against a partitioned table that can only be implemented efficiently by using an index that does not support parallel scans. The planner might choose a Parallel Append of regular Index Scan plans; each individual index scan would have to be executed to completion by a single process, but different scans could be performed at the same time by different processes.", "/versions/11/sections/4/paragraphs/0": "NOTES Each append node contains a list of one or more subplans which must be iteratively processed (forwards or backwards). Tuples are retrieved by executing the 'whichplan'th subplan until the subplan stops returning tuples, at which point that plan is shut down and the next started up.", "/versions/11/sections/4/paragraphs/1": "Append nodes don't make use of their left and right subtrees, rather they maintain a list of subplans so a typical append node looks like this in the plan tree:", "/versions/11/sections/4/paragraphs/3": "Append nodes are currently used for unions, and to support inheritance queries, where several relations need to be scanned. For example, in our standard person/student/employee/student-emp example, where student and employee inherit from person and student-emp inherits from student and employee, the query:", "/versions/11/tables/0/columns/0/label": "Text-format label", "/versions/11/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "8ee66e1c2742149a999d5d73d686e5fe02341db96cc8ee82bf91d63219f75b97"}, "evidence_kind": "source and documentation", "explain_names": ["Append"], "partial_modes": [], "comparison_data": {"node_tag": "T_Append", "strategies": [], "text_names": ["Append"], "initializer": "ExecInitAppend", "partial_modes": [], "memory_mechanism": "unclassified", "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "comparison_hash": "05fc087ef5a99b9d2d14f9b7e397d941085dafd8c263de24871ec9926b47ad8f", "explain_prefixes": ["Parallel"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeAppend.c"}, "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "12": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_Append"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "Append"}, {"label": "\u8f93\u5165", "value": "\u591a\u4e2a\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5408\u5e76\u540e\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitAppend"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "unclassified"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "234399ac20b144a86c1a815c76afc0faecdd2b0599e92fc3811a8a57c0ec3ebe", "archive_sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b"}], "mechanism": "unclassified", "description": "\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002", "source_notes": []}, "tables": [{"key": "explain-labels", "rows": [{"label": "Append", "identity": "Append"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=12", "label": "EXPLAIN"}, {"url": "/docs/12/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/12/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/enable_parallel_append/?v=12", "label": "enable_parallel_append"}], "release": {"ref": "PostgreSQL 12.22 source archive", "label": "12.22", "major": "12", "channel": "historical", "revision": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b", "source_url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "line": 1102, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1102", "sha256": "d02ea84fdaa201de5d9360645a9f24bfbd2c31f7d45a639e09560ac0e6b6471d", "archive_sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b"}, {"url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "line": 179, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:179", "sha256": "311b17379fe54e3f342fe5ad41c43afbdfa1b844978db2bb2eb22b82520d3256", "archive_sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b"}, {"url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "234399ac20b144a86c1a815c76afc0faecdd2b0599e92fc3811a8a57c0ec3ebe", "archive_sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b"}, {"url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "b0c4a0aeb48660ce06e5e700d5529ca9066fd16682bd15783d6e71b5420b07b0", "archive_sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b"}, {"url": "https://pg.center/docs/12/using-explain.html#USING-EXPLAIN-CAVEATS", "path": "using-explain.html", "label": "PostgreSQL 12.22 \u00b7 using-explain", "sha256": "06297525f2180b07e752837a3351be9c871b56559f535bcd0a67dec9baac10c0", "language": "en", "original_url": "/docs/12/using-explain.html#USING-EXPLAIN-CAVEATS"}, {"url": "https://pg.center/docs/12/parallel-plans.html#PARALLEL-APPEND", "path": "parallel-plans.html", "label": "PostgreSQL 12.22 \u00b7 parallel-plans", "sha256": "fa33380814ee65998f524524f8681d70cf3b1198d54b39847b00462b01517ffb", "language": "en", "original_url": "/docs/12/parallel-plans.html#PARALLEL-APPEND"}], "node_tag": "T_Append", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aAppend.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1aExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM."]}, {"title": "\u540c\u7248\u672c\u624b\u518c\u8bf4\u660e", "paragraphs": ["\u901a\u5e38 EXPLAIN \u663e\u793a\u89c4\u5212\u5668\u521b\u5efa\u7684\u6bcf\u4e2a\u8282\u70b9\u3002\u4f46\u6267\u884c\u5668\u6709\u65f6\u53ef\u4ee5\u6839\u636e\u89c4\u5212\u9636\u6bb5\u5c1a\u4e0d\u53ef\u77e5\u7684\u53c2\u6570\u503c\uff0c\u5224\u5b9a\u67d0\u4e9b\u8282\u70b9\u65e0\u6cd5\u4ea7\u751f\u4efb\u4f55\u884c\uff0c\u56e0\u6b64\u4e0d\u5fc5\u6267\u884c\u3002\uff08\u76ee\u524d\u4ec5\u4f1a\u53d1\u751f\u5728\u626b\u63cf\u5206\u533a\u8868\u7684 Append \u6216 MergeAppend \u8282\u70b9\u7684\u5b50\u8282\u70b9\u4e0a\u3002\uff09\u6b64\u65f6 EXPLAIN \u7701\u7565\u8fd9\u4e9b\u8282\u70b9\uff0c\u6539\u4e3a\u663e\u793a Subplans Removed: N\u3002", "\u6bcf\u5f53 PostgreSQL \u9700\u8981\u5c06\u6765\u81ea\u591a\u4e2a\u6e90\u7684\u884c\u5408\u5e76\u6210\u4e00\u4e2a\u7ed3\u679c\u96c6\u65f6\uff0c\u5b83\u5c31\u4f1a\u4f7f\u7528 Append \u6216 MergeAppend \u8ba1\u5212\u8282\u70b9\u3002\u8fd9\u79cd\u60c5\u51b5\u5e38\u89c1\u4e8e\u5b9e\u73b0 UNION ALL \u6216\u626b\u63cf\u5206\u533a\u8868\u65f6\u3002\u8fd9\u6837\u7684\u8282\u70b9\u548c\u5176\u4ed6\u4efb\u4f55\u8ba1\u5212\u4e2d\u7684\u60c5\u5f62\u4e00\u6837\uff0c\u4e5f\u53ef\u4ee5\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u3002\u4e0d\u8fc7\uff0c\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\uff0c\u89c4\u5212\u5668\u4e5f\u53ef\u80fd\u6539\u7528 Parallel Append \u8282\u70b9\u3002", "\u5f53 Append \u8282\u70b9\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u65f6\uff0c\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u4f1a\u6309\u7167\u5b50\u8ba1\u5212\u51fa\u73b0\u7684\u987a\u5e8f\u6267\u884c\u5b83\u4eec\uff0c\u56e0\u6b64\u6240\u6709\u53c2\u4e0e\u8fdb\u7a0b\u4f1a\u534f\u4f5c\u6267\u884c\u7b2c\u4e00\u4e2a\u5b50\u8ba1\u5212\u76f4\u5230\u5176\u5b8c\u6210\uff0c\u7136\u540e\u518d\u5927\u81f4\u540c\u65f6\u8f6c\u5411\u7b2c\u4e8c\u4e2a\u5b50\u8ba1\u5212\u3002\u800c\u5f53\u4f7f\u7528 Parallel Append \u65f6\uff0c\u6267\u884c\u5668\u4f1a\u5c3d\u53ef\u80fd\u5747\u5300\u5730\u5c06\u53c2\u4e0e\u8fdb\u7a0b\u5206\u6563\u5230\u5404\u4e2a\u5b50\u8ba1\u5212\u4e0a\uff0c\u4ece\u800c\u4f7f\u591a\u4e2a\u5b50\u8ba1\u5212\u80fd\u591f\u540c\u65f6\u6267\u884c\u3002\u8fd9\u6837\u65e2\u907f\u514d\u4e86\u4e89\u7528\uff0c\u4e5f\u907f\u514d\u8ba9\u90a3\u4e9b\u4ece\u672a\u6267\u884c\u67d0\u4e2a\u5b50\u8ba1\u5212\u7684\u8fdb\u7a0b\u627f\u62c5\u5176\u542f\u52a8\u4ee3\u4ef7\u3002", "\u6b64\u5916\uff0c\u4e0e\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\u53ea\u80fd\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\u7684\u666e\u901a Append \u8282\u70b9\u4e0d\u540c\uff0cParallel Append \u8282\u70b9\u65e2\u53ef\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\uff0c\u4e5f\u53ef\u5305\u542b\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u3002\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u53ea\u7531\u4e00\u4e2a\u8fdb\u7a0b\u626b\u63cf\uff0c\u56e0\u4e3a\u591a\u6b21\u626b\u63cf\u4f1a\u4ea7\u751f\u91cd\u590d\u7ed3\u679c\u3002\u56e0\u6b64\uff0c\u5373\u4f7f\u6ca1\u6709\u9ad8\u6548\u7684\u90e8\u5206\u8ba1\u5212\uff0c\u62fc\u63a5\u591a\u4e2a\u7ed3\u679c\u96c6\u7684\u8ba1\u5212\u4e5f\u80fd\u5b9e\u73b0\u7c97\u7c92\u5ea6\u5e76\u884c\u3002\u4f8b\u5982\uff0c\u9488\u5bf9\u5206\u533a\u8868\u7684\u67e5\u8be2\uff0c\u53ef\u80fd\u53ea\u6709\u501f\u52a9\u4e0d\u652f\u6301\u5e76\u884c\u626b\u63cf\u7684\u7d22\u5f15\u624d\u80fd\u9ad8\u6548\u6267\u884c\u3002\u89c4\u5212\u5668\u53ef\u80fd\u9009\u62e9\u4f7f\u7528 Parallel Append \u62fc\u63a5\u591a\u4e2a\u666e\u901a Index Scan \u8ba1\u5212\uff1b\u6bcf\u6b21\u7d22\u5f15\u626b\u63cf\u90fd\u5fc5\u987b\u7531\u5355\u4e2a\u8fdb\u7a0b\u5b8c\u6574\u6267\u884c\uff0c\u4f46\u4e0d\u540c\u626b\u63cf\u53ef\u4ee5\u7531\u4e0d\u540c\u8fdb\u7a0b\u540c\u65f6\u6267\u884c\u3002"]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["\u8bf4\u660e\uff1a\u6bcf\u4e2a Append \u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5fc5\u987b\u9010\u4e00\u5904\u7406\u7684\u5b50\u8ba1\u5212\uff0c\u65b9\u5411\u53ef\u4ee5\u6b63\u5411\u6216\u53cd\u5411\u3002\u6267\u884c\u7b2c whichplan \u4e2a\u5b50\u8ba1\u5212\u53d6\u56de\u5143\u7ec4\uff0c\u76f4\u5230\u5b83\u4e0d\u518d\u8fd4\u56de\u5143\u7ec4\uff0c\u7136\u540e\u5173\u95ed\u8be5\u8ba1\u5212\u5e76\u542f\u52a8\u4e0b\u4e00\u4e2a\u3002", "Append \u8282\u70b9\u4e0d\u4f7f\u7528\u5de6\u3001\u53f3\u5b50\u6811\uff0c\u800c\u662f\u7ef4\u62a4\u4e00\u4e2a\u5b50\u8ba1\u5212\u5217\u8868\uff0c\u56e0\u6b64\u5178\u578b\u7684 Append \u8282\u70b9\u5728\u8ba1\u5212\u6811\u4e2d\u5982\u4e0b\u6240\u793a\uff1a", "... / Append -------+------+------+--- nil / \\ | | | nil nil ... ... ... subplans", "Append \u8282\u70b9\u76ee\u524d\u7528\u4e8e\u5e76\u96c6\u64cd\u4f5c\uff0c\u4e5f\u7528\u4e8e\u9700\u8981\u626b\u63cf\u591a\u4e2a\u5173\u7cfb\u7684\u7ee7\u627f\u67e5\u8be2\u3002\u4f8b\u5982\uff0c\u5728\u6807\u51c6\u7684 person/student/employee/student-emp \u793a\u4f8b\u4e2d\uff0cstudent \u548c employee \u7ee7\u627f\u81ea person\uff0c\u800c student-emp \u540c\u65f6\u7ee7\u627f\u81ea student \u548c employee\uff0c\u67e5\u8be2\u5982\u4e0b\uff1a", "| Append -------+-------+--------+--------+ / \\ | | | | nil nil Scan Scan Scan Scan | | | | person employee student student-emp"]}, {"code": "case T_Append:\n\t\t\tpname = sname = \"Append\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u904d\u5386\u5404\u5b50\u8ba1\u5212\u5e76\u5408\u5e76\u5176\u8f93\u51fa\u884c\u3002"], "localization": {"status": "complete", "sources": [{"url": "/docs/12/parallel-plans.html", "method": "same-major semantic node", "sha256": "4aaca92475f243dcddffd80d9af558330f8f3b0ac3cbe8872b0d2901e14fe684", "language": "zh", "matched_nodes": ["#PARALLEL-PLANS/div[6]/p[1]", "#PARALLEL-PLANS/div[6]/p[2]"]}], "language": "zh", "original_text": {"/versions/12/description/0": "Visits its child plans and combines their rows.", "/versions/12/facts/0/label": "Core node tag", "/versions/12/facts/1/label": "Structured EXPLAIN Node Type", "/versions/12/facts/2/label": "Inputs", "/versions/12/facts/2/value": "Multiple child plans", "/versions/12/facts/3/label": "Output", "/versions/12/facts/3/value": "Combined tuples", "/versions/12/facts/4/label": "Executor initializer", "/versions/12/facts/5/label": "Memory mechanism", "/versions/12/tables/0/title": "EXPLAIN labels in this source build", "/versions/12/related/1/label": "Using EXPLAIN", "/versions/12/related/2/label": "Parallel plans", "/versions/12/sections/0/title": "EXPLAIN names and attributes", "/versions/12/sections/1/title": "Memory and temporary storage", "/versions/12/sections/2/title": "Parallel execution and instrumentation", "/versions/12/sections/3/title": "Same-version manual discussion", "/versions/12/sections/4/title": "Executor implementation notes", "/versions/12/sections/5/title": "EXPLAIN identity in core source", "/versions/12/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.", "/versions/12/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/12/sections/0/paragraphs/1": "Text names recorded by this source: Append.", "/versions/12/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/12/sections/1/paragraphs/0": "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.", "/versions/12/sections/2/paragraphs/0": "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.", "/versions/12/sections/2/paragraphs/1": "Callbacks in this build: ExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM.", "/versions/12/sections/3/paragraphs/0": "Normally, EXPLAIN will display every plan node created by the planner. However, there are cases where the executor can determine that certain nodes need not be executed because they cannot produce any rows, based on parameter values that were not available at planning time. (Currently this can only happen for child nodes of an Append or MergeAppend node that is scanning a partitioned table.) When this happens, those plan nodes are omitted from the EXPLAIN output and a Subplans Removed: N annotation appears instead.", "/versions/12/sections/3/paragraphs/1": "Whenever PostgreSQL needs to combine rows from multiple sources into a single result set, it uses an Append or MergeAppend plan node. This commonly happens when implementing UNION ALL or when scanning a partitioned table. Such nodes can be used in parallel plans just as they can in any other plan. However, in a parallel plan, the planner may instead use a Parallel Append node.", "/versions/12/sections/3/paragraphs/2": "When an Append node is used in a parallel plan, each process will execute the child plans in the order in which they appear, so that all participating processes cooperate to execute the first child plan until it is complete and then move to the second plan at around the same time. When a Parallel Append is used instead, the executor will instead spread out the participating processes as evenly as possible across its child plans, so that multiple child plans are executed simultaneously. This avoids contention, and also avoids paying the startup cost of a child plan in those processes that never execute it.", "/versions/12/sections/3/paragraphs/3": "Also, unlike a regular Append node, which can only have partial children when used within a parallel plan, a Parallel Append node can have both partial and non-partial child plans. Non-partial children will be scanned by only a single process, since scanning them more than once would produce duplicate results. Plans that involve appending multiple results sets can therefore achieve coarse-grained parallelism even when efficient partial plans are not available. For example, consider a query against a partitioned table that can only be implemented efficiently by using an index that does not support parallel scans. The planner might choose a Parallel Append of regular Index Scan plans; each individual index scan would have to be executed to completion by a single process, but different scans could be performed at the same time by different processes.", "/versions/12/sections/4/paragraphs/0": "NOTES Each append node contains a list of one or more subplans which must be iteratively processed (forwards or backwards). Tuples are retrieved by executing the 'whichplan'th subplan until the subplan stops returning tuples, at which point that plan is shut down and the next started up.", "/versions/12/sections/4/paragraphs/1": "Append nodes don't make use of their left and right subtrees, rather they maintain a list of subplans so a typical append node looks like this in the plan tree:", "/versions/12/sections/4/paragraphs/3": "Append nodes are currently used for unions, and to support inheritance queries, where several relations need to be scanned. For example, in our standard person/student/employee/student-emp example, where student and employee inherit from person and student-emp inherits from student and employee, the query:", "/versions/12/tables/0/columns/0/label": "Text-format label", "/versions/12/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "b2cbed2a588328be3c30a0c08e6427e64eac43831441ce6ea9c582b528da7460"}, "evidence_kind": "source and documentation", "explain_names": ["Append"], "partial_modes": [], "comparison_data": {"node_tag": "T_Append", "strategies": [], "text_names": ["Append"], "initializer": "ExecInitAppend", "partial_modes": [], "memory_mechanism": "unclassified", "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "comparison_hash": "05fc087ef5a99b9d2d14f9b7e397d941085dafd8c263de24871ec9926b47ad8f", "explain_prefixes": ["Parallel"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeAppend.c"}, "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "13": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_Append"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "Append"}, {"label": "\u8f93\u5165", "value": "\u591a\u4e2a\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5408\u5e76\u540e\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitAppend"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "unclassified"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "88f6548e32dfd163c7e4b1d01f1b10ff92911860aa7ff602f324c0b1c200ed47", "archive_sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6"}], "mechanism": "unclassified", "description": "\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002", "source_notes": []}, "tables": [{"key": "explain-labels", "rows": [{"label": "Append", "identity": "Append"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=13", "label": "EXPLAIN"}, {"url": "/docs/13/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/13/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/enable_parallel_append/?v=13", "label": "enable_parallel_append"}], "release": {"ref": "PostgreSQL 13.23 source archive", "label": "13.23", "major": "13", "channel": "historical", "revision": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6", "source_url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "line": 1160, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1160", "sha256": "541713e0e7f1c9cc352c2b6028964d440c19d2678a4463000094c24a88c1e730", "archive_sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6"}, {"url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "line": 179, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:179", "sha256": "d085ee99acfa00587e6ade3a1d9f8108a0566beedbbee3f54a50c9fc0cc2e875", "archive_sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6"}, {"url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "88f6548e32dfd163c7e4b1d01f1b10ff92911860aa7ff602f324c0b1c200ed47", "archive_sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6"}, {"url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "dcb296833777b02008c4b6bae8e8f7c6423b7ffba21f36702597c9d596d039ab", "archive_sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6"}, {"url": "https://pg.center/docs/13/using-explain.html#USING-EXPLAIN-CAVEATS", "path": "using-explain.html", "label": "PostgreSQL 13.23 \u00b7 using-explain", "sha256": "650fd8629382d5dc8f9f8412c50ec5f32442a9ad2f98ca88e5348a7c2bd0ac7a", "language": "en", "original_url": "/docs/13/using-explain.html#USING-EXPLAIN-CAVEATS"}, {"url": "https://pg.center/docs/13/parallel-plans.html#PARALLEL-APPEND", "path": "parallel-plans.html", "label": "PostgreSQL 13.23 \u00b7 parallel-plans", "sha256": "025ad8564a8461b676c9153f9e084429cca0ef86c968090689b082120060f3d0", "language": "en", "original_url": "/docs/13/parallel-plans.html#PARALLEL-APPEND"}], "node_tag": "T_Append", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aAppend.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1aExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM."]}, {"title": "\u540c\u7248\u672c\u624b\u518c\u8bf4\u660e", "paragraphs": ["\u901a\u5e38 EXPLAIN \u663e\u793a\u89c4\u5212\u5668\u521b\u5efa\u7684\u6bcf\u4e2a\u8282\u70b9\u3002\u4f46\u6267\u884c\u5668\u6709\u65f6\u53ef\u4ee5\u6839\u636e\u89c4\u5212\u9636\u6bb5\u5c1a\u4e0d\u53ef\u77e5\u7684\u53c2\u6570\u503c\uff0c\u5224\u5b9a\u67d0\u4e9b\u8282\u70b9\u65e0\u6cd5\u4ea7\u751f\u4efb\u4f55\u884c\uff0c\u56e0\u6b64\u4e0d\u5fc5\u6267\u884c\u3002\uff08\u76ee\u524d\u4ec5\u4f1a\u53d1\u751f\u5728\u626b\u63cf\u5206\u533a\u8868\u7684 Append \u6216 MergeAppend \u8282\u70b9\u7684\u5b50\u8282\u70b9\u4e0a\u3002\uff09\u6b64\u65f6 EXPLAIN \u7701\u7565\u8fd9\u4e9b\u8282\u70b9\uff0c\u6539\u4e3a\u663e\u793a Subplans Removed: N\u3002", "\u6bcf\u5f53 PostgreSQL \u9700\u8981\u5c06\u6765\u81ea\u591a\u4e2a\u6e90\u7684\u884c\u5408\u5e76\u6210\u4e00\u4e2a\u7ed3\u679c\u96c6\u65f6\uff0c\u5b83\u5c31\u4f1a\u4f7f\u7528 Append \u6216 MergeAppend \u8ba1\u5212\u8282\u70b9\u3002\u8fd9\u79cd\u60c5\u51b5\u5e38\u89c1\u4e8e\u5b9e\u73b0 UNION ALL \u6216\u626b\u63cf\u5206\u533a\u8868\u65f6\u3002\u8fd9\u6837\u7684\u8282\u70b9\u548c\u5176\u4ed6\u4efb\u4f55\u8ba1\u5212\u4e2d\u7684\u60c5\u5f62\u4e00\u6837\uff0c\u4e5f\u53ef\u4ee5\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u3002\u4e0d\u8fc7\uff0c\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\uff0c\u89c4\u5212\u5668\u4e5f\u53ef\u80fd\u6539\u7528 Parallel Append \u8282\u70b9\u3002", "\u5f53 Append \u8282\u70b9\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u65f6\uff0c\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u4f1a\u6309\u7167\u5b50\u8ba1\u5212\u51fa\u73b0\u7684\u987a\u5e8f\u6267\u884c\u5b83\u4eec\uff0c\u56e0\u6b64\u6240\u6709\u53c2\u4e0e\u8fdb\u7a0b\u4f1a\u534f\u4f5c\u6267\u884c\u7b2c\u4e00\u4e2a\u5b50\u8ba1\u5212\u76f4\u5230\u5176\u5b8c\u6210\uff0c\u7136\u540e\u518d\u5927\u81f4\u540c\u65f6\u8f6c\u5411\u7b2c\u4e8c\u4e2a\u5b50\u8ba1\u5212\u3002\u800c\u5f53\u4f7f\u7528 Parallel Append \u65f6\uff0c\u6267\u884c\u5668\u4f1a\u5c3d\u53ef\u80fd\u5747\u5300\u5730\u5c06\u53c2\u4e0e\u8fdb\u7a0b\u5206\u6563\u5230\u5404\u4e2a\u5b50\u8ba1\u5212\u4e0a\uff0c\u4ece\u800c\u4f7f\u591a\u4e2a\u5b50\u8ba1\u5212\u80fd\u591f\u540c\u65f6\u6267\u884c\u3002\u8fd9\u6837\u65e2\u907f\u514d\u4e86\u4e89\u7528\uff0c\u4e5f\u907f\u514d\u8ba9\u90a3\u4e9b\u4ece\u672a\u6267\u884c\u67d0\u4e2a\u5b50\u8ba1\u5212\u7684\u8fdb\u7a0b\u627f\u62c5\u5176\u542f\u52a8\u4ee3\u4ef7\u3002", "\u6b64\u5916\uff0c\u4e0e\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\u53ea\u80fd\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\u7684\u666e\u901a Append \u8282\u70b9\u4e0d\u540c\uff0cParallel Append \u8282\u70b9\u65e2\u53ef\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\uff0c\u4e5f\u53ef\u5305\u542b\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u3002\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u53ea\u7531\u4e00\u4e2a\u8fdb\u7a0b\u626b\u63cf\uff0c\u56e0\u4e3a\u591a\u6b21\u626b\u63cf\u4f1a\u4ea7\u751f\u91cd\u590d\u7ed3\u679c\u3002\u56e0\u6b64\uff0c\u5373\u4f7f\u6ca1\u6709\u9ad8\u6548\u7684\u90e8\u5206\u8ba1\u5212\uff0c\u62fc\u63a5\u591a\u4e2a\u7ed3\u679c\u96c6\u7684\u8ba1\u5212\u4e5f\u80fd\u5b9e\u73b0\u7c97\u7c92\u5ea6\u5e76\u884c\u3002\u4f8b\u5982\uff0c\u9488\u5bf9\u5206\u533a\u8868\u7684\u67e5\u8be2\uff0c\u53ef\u80fd\u53ea\u6709\u501f\u52a9\u4e0d\u652f\u6301\u5e76\u884c\u626b\u63cf\u7684\u7d22\u5f15\u624d\u80fd\u9ad8\u6548\u6267\u884c\u3002\u89c4\u5212\u5668\u53ef\u80fd\u9009\u62e9\u4f7f\u7528 Parallel Append \u62fc\u63a5\u591a\u4e2a\u666e\u901a Index Scan \u8ba1\u5212\uff1b\u6bcf\u6b21\u7d22\u5f15\u626b\u63cf\u90fd\u5fc5\u987b\u7531\u5355\u4e2a\u8fdb\u7a0b\u5b8c\u6574\u6267\u884c\uff0c\u4f46\u4e0d\u540c\u626b\u63cf\u53ef\u4ee5\u7531\u4e0d\u540c\u8fdb\u7a0b\u540c\u65f6\u6267\u884c\u3002"]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["\u8bf4\u660e\uff1a\u6bcf\u4e2a Append \u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5fc5\u987b\u9010\u4e00\u5904\u7406\u7684\u5b50\u8ba1\u5212\uff0c\u65b9\u5411\u53ef\u4ee5\u6b63\u5411\u6216\u53cd\u5411\u3002\u6267\u884c\u7b2c whichplan \u4e2a\u5b50\u8ba1\u5212\u53d6\u56de\u5143\u7ec4\uff0c\u76f4\u5230\u5b83\u4e0d\u518d\u8fd4\u56de\u5143\u7ec4\uff0c\u7136\u540e\u5173\u95ed\u8be5\u8ba1\u5212\u5e76\u542f\u52a8\u4e0b\u4e00\u4e2a\u3002", "Append \u8282\u70b9\u4e0d\u4f7f\u7528\u5de6\u3001\u53f3\u5b50\u6811\uff0c\u800c\u662f\u7ef4\u62a4\u4e00\u4e2a\u5b50\u8ba1\u5212\u5217\u8868\uff0c\u56e0\u6b64\u5178\u578b\u7684 Append \u8282\u70b9\u5728\u8ba1\u5212\u6811\u4e2d\u5982\u4e0b\u6240\u793a\uff1a", "... / Append -------+------+------+--- nil / \\ | | | nil nil ... ... ... subplans", "Append \u8282\u70b9\u76ee\u524d\u7528\u4e8e\u5e76\u96c6\u64cd\u4f5c\uff0c\u4e5f\u7528\u4e8e\u9700\u8981\u626b\u63cf\u591a\u4e2a\u5173\u7cfb\u7684\u7ee7\u627f\u67e5\u8be2\u3002\u4f8b\u5982\uff0c\u5728\u6807\u51c6\u7684 person/student/employee/student-emp \u793a\u4f8b\u4e2d\uff0cstudent \u548c employee \u7ee7\u627f\u81ea person\uff0c\u800c student-emp \u540c\u65f6\u7ee7\u627f\u81ea student \u548c employee\uff0c\u67e5\u8be2\u5982\u4e0b\uff1a", "| Append -------+-------+--------+--------+ / \\ | | | | nil nil Scan Scan Scan Scan | | | | person employee student student-emp"]}, {"code": "case T_Append:\n\t\t\tpname = sname = \"Append\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u904d\u5386\u5404\u5b50\u8ba1\u5212\u5e76\u5408\u5e76\u5176\u8f93\u51fa\u884c\u3002"], "localization": {"status": "complete", "sources": [{"url": "/docs/13/parallel-plans.html", "method": "same-major semantic node", "sha256": "bbbbbd9cc27db6811c388e9c4951a9641c48871942bc709cec203e4271518c50", "language": "zh", "matched_nodes": ["#PARALLEL-PLANS/div[6]/p[1]", "#PARALLEL-PLANS/div[6]/p[2]"]}], "language": "zh", "original_text": {"/versions/13/description/0": "Visits its child plans and combines their rows.", "/versions/13/facts/0/label": "Core node tag", "/versions/13/facts/1/label": "Structured EXPLAIN Node Type", "/versions/13/facts/2/label": "Inputs", "/versions/13/facts/2/value": "Multiple child plans", "/versions/13/facts/3/label": "Output", "/versions/13/facts/3/value": "Combined tuples", "/versions/13/facts/4/label": "Executor initializer", "/versions/13/facts/5/label": "Memory mechanism", "/versions/13/tables/0/title": "EXPLAIN labels in this source build", "/versions/13/related/1/label": "Using EXPLAIN", "/versions/13/related/2/label": "Parallel plans", "/versions/13/sections/0/title": "EXPLAIN names and attributes", "/versions/13/sections/1/title": "Memory and temporary storage", "/versions/13/sections/2/title": "Parallel execution and instrumentation", "/versions/13/sections/3/title": "Same-version manual discussion", "/versions/13/sections/4/title": "Executor implementation notes", "/versions/13/sections/5/title": "EXPLAIN identity in core source", "/versions/13/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.", "/versions/13/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/13/sections/0/paragraphs/1": "Text names recorded by this source: Append.", "/versions/13/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/13/sections/1/paragraphs/0": "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.", "/versions/13/sections/2/paragraphs/0": "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.", "/versions/13/sections/2/paragraphs/1": "Callbacks in this build: ExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM.", "/versions/13/sections/3/paragraphs/0": "Normally, EXPLAIN will display every plan node created by the planner. However, there are cases where the executor can determine that certain nodes need not be executed because they cannot produce any rows, based on parameter values that were not available at planning time. (Currently this can only happen for child nodes of an Append or MergeAppend node that is scanning a partitioned table.) When this happens, those plan nodes are omitted from the EXPLAIN output and a Subplans Removed: N annotation appears instead.", "/versions/13/sections/3/paragraphs/1": "Whenever PostgreSQL needs to combine rows from multiple sources into a single result set, it uses an Append or MergeAppend plan node. This commonly happens when implementing UNION ALL or when scanning a partitioned table. Such nodes can be used in parallel plans just as they can in any other plan. However, in a parallel plan, the planner may instead use a Parallel Append node.", "/versions/13/sections/3/paragraphs/2": "When an Append node is used in a parallel plan, each process will execute the child plans in the order in which they appear, so that all participating processes cooperate to execute the first child plan until it is complete and then move to the second plan at around the same time. When a Parallel Append is used instead, the executor will instead spread out the participating processes as evenly as possible across its child plans, so that multiple child plans are executed simultaneously. This avoids contention, and also avoids paying the startup cost of a child plan in those processes that never execute it.", "/versions/13/sections/3/paragraphs/3": "Also, unlike a regular Append node, which can only have partial children when used within a parallel plan, a Parallel Append node can have both partial and non-partial child plans. Non-partial children will be scanned by only a single process, since scanning them more than once would produce duplicate results. Plans that involve appending multiple results sets can therefore achieve coarse-grained parallelism even when efficient partial plans are not available. For example, consider a query against a partitioned table that can only be implemented efficiently by using an index that does not support parallel scans. The planner might choose a Parallel Append of regular Index Scan plans; each individual index scan would have to be executed to completion by a single process, but different scans could be performed at the same time by different processes.", "/versions/13/sections/4/paragraphs/0": "NOTES Each append node contains a list of one or more subplans which must be iteratively processed (forwards or backwards). Tuples are retrieved by executing the 'whichplan'th subplan until the subplan stops returning tuples, at which point that plan is shut down and the next started up.", "/versions/13/sections/4/paragraphs/1": "Append nodes don't make use of their left and right subtrees, rather they maintain a list of subplans so a typical append node looks like this in the plan tree:", "/versions/13/sections/4/paragraphs/3": "Append nodes are currently used for unions, and to support inheritance queries, where several relations need to be scanned. For example, in our standard person/student/employee/student-emp example, where student and employee inherit from person and student-emp inherits from student and employee, the query:", "/versions/13/tables/0/columns/0/label": "Text-format label", "/versions/13/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "cf834c12c27af7417ef8f01f7a637292b480a10f4bdbe952db1fa3601a2a2990"}, "evidence_kind": "source and documentation", "explain_names": ["Append"], "partial_modes": [], "comparison_data": {"node_tag": "T_Append", "strategies": [], "text_names": ["Append"], "initializer": "ExecInitAppend", "partial_modes": [], "memory_mechanism": "unclassified", "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "comparison_hash": "05fc087ef5a99b9d2d14f9b7e397d941085dafd8c263de24871ec9926b47ad8f", "explain_prefixes": ["Parallel"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeAppend.c"}, "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "14": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_Append"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "Append"}, {"label": "\u8f93\u5165", "value": "\u591a\u4e2a\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5408\u5e76\u540e\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitAppend"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "unclassified"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "46c6e5fff86418c90b3708013990f4806c44dc9da7ec6e8a7577f64a4ad1c85c", "archive_sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897"}], "mechanism": "unclassified", "description": "\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002", "source_notes": []}, "tables": [{"key": "explain-labels", "rows": [{"label": "Append", "identity": "Append"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=14", "label": "EXPLAIN"}, {"url": "/docs/14/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/14/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/enable_parallel_append/?v=14", "label": "enable_parallel_append"}, {"url": "/wiki/guc/enable_async_append/?v=14", "label": "enable_async_append"}], "release": {"ref": "PostgreSQL 14.24 source archive", "label": "14.24", "major": "14", "channel": "stable", "revision": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897", "source_url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "line": 1196, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1196", "sha256": "e091be4e2a083b8dea39ccd09beedede22c1716ef974da66c214a44f48be8c41", "archive_sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897"}, {"url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "line": 181, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:181", "sha256": "72da1c5ad457f1d92a39ab73531701794df858419e3b89d6e6cb7079634e68fa", "archive_sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897"}, {"url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "46c6e5fff86418c90b3708013990f4806c44dc9da7ec6e8a7577f64a4ad1c85c", "archive_sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897"}, {"url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "302f51a16b570dba7ec4e7bc045f7df5800d21630280354d1a24025f3baec75d", "archive_sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897"}, {"url": "https://pg.center/docs/14/using-explain.html#USING-EXPLAIN-CAVEATS", "path": "using-explain.html", "label": "PostgreSQL 14.24 \u00b7 using-explain", "sha256": "7f5ab59cb21a035ada45ea3426c5d1cca3f781273483677f73fdd76753555206", "language": "en", "original_url": "/docs/14/using-explain.html#USING-EXPLAIN-CAVEATS"}, {"url": "https://pg.center/docs/14/parallel-plans.html#PARALLEL-APPEND", "path": "parallel-plans.html", "label": "PostgreSQL 14.24 \u00b7 parallel-plans", "sha256": "71fc3525781b74150364925e123cd8598fdebe0e05326706f2bc2e1ffa0b88a4", "language": "en", "original_url": "/docs/14/parallel-plans.html#PARALLEL-APPEND"}, {"url": "https://pg.center/docs/14/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 14.24 \u00b7 using-explain", "sha256": "7f5ab59cb21a035ada45ea3426c5d1cca3f781273483677f73fdd76753555206", "language": "en", "original_url": "/docs/14/using-explain.html#USING-EXPLAIN-ANALYZE"}], "node_tag": "T_Append", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aAppend.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1aExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM."]}, {"title": "\u540c\u7248\u672c\u624b\u518c\u8bf4\u660e", "paragraphs": ["\u901a\u5e38 EXPLAIN \u663e\u793a\u89c4\u5212\u5668\u521b\u5efa\u7684\u6bcf\u4e2a\u8282\u70b9\u3002\u4f46\u6267\u884c\u5668\u6709\u65f6\u53ef\u4ee5\u6839\u636e\u89c4\u5212\u9636\u6bb5\u5c1a\u4e0d\u53ef\u77e5\u7684\u53c2\u6570\u503c\uff0c\u5224\u5b9a\u67d0\u4e9b\u8282\u70b9\u65e0\u6cd5\u4ea7\u751f\u4efb\u4f55\u884c\uff0c\u56e0\u6b64\u4e0d\u5fc5\u6267\u884c\u3002\uff08\u76ee\u524d\u4ec5\u4f1a\u53d1\u751f\u5728\u626b\u63cf\u5206\u533a\u8868\u7684 Append \u6216 MergeAppend \u8282\u70b9\u7684\u5b50\u8282\u70b9\u4e0a\u3002\uff09\u6b64\u65f6 EXPLAIN \u7701\u7565\u8fd9\u4e9b\u8282\u70b9\uff0c\u6539\u4e3a\u663e\u793a Subplans Removed: N\u3002", "\u6bcf\u5f53 PostgreSQL \u9700\u8981\u5c06\u6765\u81ea\u591a\u4e2a\u6e90\u7684\u884c\u5408\u5e76\u6210\u4e00\u4e2a\u7ed3\u679c\u96c6\u65f6\uff0c\u5b83\u5c31\u4f1a\u4f7f\u7528 Append \u6216 MergeAppend \u8ba1\u5212\u8282\u70b9\u3002\u8fd9\u79cd\u60c5\u51b5\u5e38\u89c1\u4e8e\u5b9e\u73b0 UNION ALL \u6216\u626b\u63cf\u5206\u533a\u8868\u65f6\u3002\u8fd9\u6837\u7684\u8282\u70b9\u548c\u5176\u4ed6\u4efb\u4f55\u8ba1\u5212\u4e2d\u7684\u60c5\u5f62\u4e00\u6837\uff0c\u4e5f\u53ef\u4ee5\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u3002\u4e0d\u8fc7\uff0c\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\uff0c\u89c4\u5212\u5668\u4e5f\u53ef\u80fd\u6539\u7528 Parallel Append \u8282\u70b9\u3002", "\u5f53 Append \u8282\u70b9\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u65f6\uff0c\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u4f1a\u6309\u7167\u5b50\u8ba1\u5212\u51fa\u73b0\u7684\u987a\u5e8f\u6267\u884c\u5b83\u4eec\uff0c\u56e0\u6b64\u6240\u6709\u53c2\u4e0e\u8fdb\u7a0b\u4f1a\u534f\u4f5c\u6267\u884c\u7b2c\u4e00\u4e2a\u5b50\u8ba1\u5212\u76f4\u5230\u5176\u5b8c\u6210\uff0c\u7136\u540e\u518d\u5927\u81f4\u540c\u65f6\u8f6c\u5411\u7b2c\u4e8c\u4e2a\u5b50\u8ba1\u5212\u3002\u800c\u5f53\u4f7f\u7528 Parallel Append \u65f6\uff0c\u6267\u884c\u5668\u4f1a\u5c3d\u53ef\u80fd\u5747\u5300\u5730\u5c06\u53c2\u4e0e\u8fdb\u7a0b\u5206\u6563\u5230\u5404\u4e2a\u5b50\u8ba1\u5212\u4e0a\uff0c\u4ece\u800c\u4f7f\u591a\u4e2a\u5b50\u8ba1\u5212\u80fd\u591f\u540c\u65f6\u6267\u884c\u3002\u8fd9\u6837\u65e2\u907f\u514d\u4e86\u4e89\u7528\uff0c\u4e5f\u907f\u514d\u8ba9\u90a3\u4e9b\u4ece\u672a\u6267\u884c\u67d0\u4e2a\u5b50\u8ba1\u5212\u7684\u8fdb\u7a0b\u627f\u62c5\u5176\u542f\u52a8\u4ee3\u4ef7\u3002", "\u6b64\u5916\uff0c\u4e0e\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\u53ea\u80fd\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\u7684\u666e\u901a Append \u8282\u70b9\u4e0d\u540c\uff0cParallel Append \u8282\u70b9\u65e2\u53ef\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\uff0c\u4e5f\u53ef\u5305\u542b\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u3002\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u53ea\u7531\u4e00\u4e2a\u8fdb\u7a0b\u626b\u63cf\uff0c\u56e0\u4e3a\u591a\u6b21\u626b\u63cf\u4f1a\u4ea7\u751f\u91cd\u590d\u7ed3\u679c\u3002\u56e0\u6b64\uff0c\u5373\u4f7f\u6ca1\u6709\u9ad8\u6548\u7684\u90e8\u5206\u8ba1\u5212\uff0c\u62fc\u63a5\u591a\u4e2a\u7ed3\u679c\u96c6\u7684\u8ba1\u5212\u4e5f\u80fd\u5b9e\u73b0\u7c97\u7c92\u5ea6\u5e76\u884c\u3002\u4f8b\u5982\uff0c\u9488\u5bf9\u5206\u533a\u8868\u7684\u67e5\u8be2\uff0c\u53ef\u80fd\u53ea\u6709\u501f\u52a9\u4e0d\u652f\u6301\u5e76\u884c\u626b\u63cf\u7684\u7d22\u5f15\u624d\u80fd\u9ad8\u6548\u6267\u884c\u3002\u89c4\u5212\u5668\u53ef\u80fd\u9009\u62e9\u4f7f\u7528 Parallel Append \u62fc\u63a5\u591a\u4e2a\u666e\u901a Index Scan \u8ba1\u5212\uff1b\u6bcf\u6b21\u7d22\u5f15\u626b\u63cf\u90fd\u5fc5\u987b\u7531\u5355\u4e2a\u8fdb\u7a0b\u5b8c\u6574\u6267\u884c\uff0c\u4f46\u4e0d\u540c\u626b\u63cf\u53ef\u4ee5\u7531\u4e0d\u540c\u8fdb\u7a0b\u540c\u65f6\u6267\u884c\u3002"]}, {"title": "\u672c\u7248\u624b\u518c\u4e2d\u7684\u793a\u4f8b", "blocks": [{"code": "EXPLAIN UPDATE parent SET f2 = f2 + 1 WHERE f1 = 101;\n                                              QUERY PLAN\n------------------------------------------------------------------------------------------------------\n Update on parent  (cost=0.00..24.59 rows=0 width=0)\n   Update on parent parent_1\n   Update on child1 parent_2\n   Update on child2 parent_3\n   Update on child3 parent_4\n   ->  Result  (cost=0.00..24.59 rows=4 width=14)\n         ->  Append  (cost=0.00..24.54 rows=4 width=14)\n               ->  Seq Scan on parent parent_1  (cost=0.00..0.00 rows=1 width=14)\n                     Filter: (f1 = 101)\n               ->  Index Scan using child1_pkey on child1 parent_2  (cost=0.15..8.17 rows=1 width=14)\n                     Index Cond: (f1 = 101)\n               ->  Index Scan using child2_pkey on child2 parent_3  (cost=0.15..8.17 rows=1 width=14)\n                     Index Cond: (f1 = 101)\n               ->  Index Scan using child3_pkey on child3 parent_4  (cost=0.15..8.17 rows=1 width=14)\n                     Index Cond: (f1 = 101)", "source": {"url": "/docs/14/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 14.24 \u00b7 using-explain", "sha256": "7f5ab59cb21a035ada45ea3426c5d1cca3f781273483677f73fdd76753555206"}, "paragraphs": ["\u793a\u4f8b\u6458\u81ea PostgreSQL 14.24 \u624b\u518c\uff1b\u672c\u767e\u79d1\u672a\u5b9e\u9645\u6267\u884c\u6b64\u793a\u4f8b\u3002", "UPDATE \u6216 DELETE \u547d\u4ee4\u5f71\u54cd\u7ee7\u627f\u5c42\u7ea7\u65f6\uff0c\u8f93\u51fa\u53ef\u80fd\u5982\u4e0b\uff1a"]}]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["\u8bf4\u660e\uff1a\u6bcf\u4e2a Append \u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5fc5\u987b\u9010\u4e00\u5904\u7406\u7684\u5b50\u8ba1\u5212\uff0c\u65b9\u5411\u53ef\u4ee5\u6b63\u5411\u6216\u53cd\u5411\u3002\u6267\u884c\u7b2c whichplan \u4e2a\u5b50\u8ba1\u5212\u53d6\u56de\u5143\u7ec4\uff0c\u76f4\u5230\u5b83\u4e0d\u518d\u8fd4\u56de\u5143\u7ec4\uff0c\u7136\u540e\u5173\u95ed\u8be5\u8ba1\u5212\u5e76\u542f\u52a8\u4e0b\u4e00\u4e2a\u3002", "Append \u8282\u70b9\u4e0d\u4f7f\u7528\u5de6\u3001\u53f3\u5b50\u6811\uff0c\u800c\u662f\u7ef4\u62a4\u4e00\u4e2a\u5b50\u8ba1\u5212\u5217\u8868\uff0c\u56e0\u6b64\u5178\u578b\u7684 Append \u8282\u70b9\u5728\u8ba1\u5212\u6811\u4e2d\u5982\u4e0b\u6240\u793a\uff1a", "... / Append -------+------+------+--- nil / \\ | | | nil nil ... ... ... subplans", "Append \u8282\u70b9\u76ee\u524d\u7528\u4e8e\u5e76\u96c6\u64cd\u4f5c\uff0c\u4e5f\u7528\u4e8e\u9700\u8981\u626b\u63cf\u591a\u4e2a\u5173\u7cfb\u7684\u7ee7\u627f\u67e5\u8be2\u3002\u4f8b\u5982\uff0c\u5728\u6807\u51c6\u7684 person/student/employee/student-emp \u793a\u4f8b\u4e2d\uff0cstudent \u548c employee \u7ee7\u627f\u81ea person\uff0c\u800c student-emp \u540c\u65f6\u7ee7\u627f\u81ea student \u548c employee\uff0c\u67e5\u8be2\u5982\u4e0b\uff1a", "| Append -------+-------+--------+--------+ / \\ | | | | nil nil Scan Scan Scan Scan | | | | person employee student student-emp"]}, {"code": "case T_Append:\n\t\t\tpname = sname = \"Append\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u904d\u5386\u5404\u5b50\u8ba1\u5212\u5e76\u5408\u5e76\u5176\u8f93\u51fa\u884c\u3002"], "localization": {"status": "complete", "sources": [{"url": "/docs/14/parallel-plans.html", "method": "same-major semantic node", "sha256": "27ba0fab61ef7b5aa518b18597a7cd30f9560e5cf2b383016d31e59518892f88", "language": "zh", "matched_nodes": ["#PARALLEL-PLANS/div[6]/p[1]", "#PARALLEL-PLANS/div[6]/p[2]"]}], "language": "zh", "original_text": {"/versions/14/description/0": "Visits its child plans and combines their rows.", "/versions/14/facts/0/label": "Core node tag", "/versions/14/facts/1/label": "Structured EXPLAIN Node Type", "/versions/14/facts/2/label": "Inputs", "/versions/14/facts/2/value": "Multiple child plans", "/versions/14/facts/3/label": "Output", "/versions/14/facts/3/value": "Combined tuples", "/versions/14/facts/4/label": "Executor initializer", "/versions/14/facts/5/label": "Memory mechanism", "/versions/14/tables/0/title": "EXPLAIN labels in this source build", "/versions/14/related/1/label": "Using EXPLAIN", "/versions/14/related/2/label": "Parallel plans", "/versions/14/sections/0/title": "EXPLAIN names and attributes", "/versions/14/sections/1/title": "Memory and temporary storage", "/versions/14/sections/2/title": "Parallel execution and instrumentation", "/versions/14/sections/3/title": "Same-version manual discussion", "/versions/14/sections/4/title": "Examples from this manual build", "/versions/14/sections/5/title": "Executor implementation notes", "/versions/14/sections/6/title": "EXPLAIN identity in core source", "/versions/14/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.", "/versions/14/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/14/sections/0/paragraphs/1": "Text names recorded by this source: Append.", "/versions/14/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/14/sections/1/paragraphs/0": "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.", "/versions/14/sections/2/paragraphs/0": "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.", "/versions/14/sections/2/paragraphs/1": "Callbacks in this build: ExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM.", "/versions/14/sections/3/paragraphs/0": "Normally, EXPLAIN will display every plan node created by the planner. However, there are cases where the executor can determine that certain nodes need not be executed because they cannot produce any rows, based on parameter values that were not available at planning time. (Currently this can only happen for child nodes of an Append or MergeAppend node that is scanning a partitioned table.) When this happens, those plan nodes are omitted from the EXPLAIN output and a Subplans Removed: N annotation appears instead.", "/versions/14/sections/3/paragraphs/1": "Whenever PostgreSQL needs to combine rows from multiple sources into a single result set, it uses an Append or MergeAppend plan node. This commonly happens when implementing UNION ALL or when scanning a partitioned table. Such nodes can be used in parallel plans just as they can in any other plan. However, in a parallel plan, the planner may instead use a Parallel Append node.", "/versions/14/sections/3/paragraphs/2": "When an Append node is used in a parallel plan, each process will execute the child plans in the order in which they appear, so that all participating processes cooperate to execute the first child plan until it is complete and then move to the second plan at around the same time. When a Parallel Append is used instead, the executor will instead spread out the participating processes as evenly as possible across its child plans, so that multiple child plans are executed simultaneously. This avoids contention, and also avoids paying the startup cost of a child plan in those processes that never execute it.", "/versions/14/sections/3/paragraphs/3": "Also, unlike a regular Append node, which can only have partial children when used within a parallel plan, a Parallel Append node can have both partial and non-partial child plans. Non-partial children will be scanned by only a single process, since scanning them more than once would produce duplicate results. Plans that involve appending multiple results sets can therefore achieve coarse-grained parallelism even when efficient partial plans are not available. For example, consider a query against a partitioned table that can only be implemented efficiently by using an index that does not support parallel scans. The planner might choose a Parallel Append of regular Index Scan plans; each individual index scan would have to be executed to completion by a single process, but different scans could be performed at the same time by different processes.", "/versions/14/sections/5/paragraphs/0": "NOTES Each append node contains a list of one or more subplans which must be iteratively processed (forwards or backwards). Tuples are retrieved by executing the 'whichplan'th subplan until the subplan stops returning tuples, at which point that plan is shut down and the next started up.", "/versions/14/sections/5/paragraphs/1": "Append nodes don't make use of their left and right subtrees, rather they maintain a list of subplans so a typical append node looks like this in the plan tree:", "/versions/14/sections/5/paragraphs/3": "Append nodes are currently used for unions, and to support inheritance queries, where several relations need to be scanned. For example, in our standard person/student/employee/student-emp example, where student and employee inherit from person and student-emp inherits from student and employee, the query:", "/versions/14/tables/0/columns/0/label": "Text-format label", "/versions/14/tables/0/columns/1/label": "Structured node identity", "/versions/14/sections/4/blocks/0/paragraphs/0": "Example copied from the PostgreSQL 14.24 manual; it was not executed for this collection.", "/versions/14/sections/4/blocks/0/paragraphs/1": "When an UPDATE or DELETE command affects an inheritance hierarchy, the output might look like this:"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "98f86d7bba35c3e5df4d265682c053b53a819bc91a5d968f30b2ddd3f14bbf06"}, "evidence_kind": "source and documentation", "explain_names": ["Append"], "partial_modes": [], "comparison_data": {"node_tag": "T_Append", "strategies": [], "text_names": ["Append"], "initializer": "ExecInitAppend", "partial_modes": [], "memory_mechanism": "unclassified", "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "comparison_hash": "05fc087ef5a99b9d2d14f9b7e397d941085dafd8c263de24871ec9926b47ad8f", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeAppend.c"}, "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "15": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_Append"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "Append"}, {"label": "\u8f93\u5165", "value": "\u591a\u4e2a\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5408\u5e76\u540e\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitAppend"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "unclassified"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "bf508a0efe0cd78f222a6994773b2095f744155ea12935e7fde95b60321393ce", "archive_sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89"}], "mechanism": "unclassified", "description": "\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002", "source_notes": []}, "tables": [{"key": "explain-labels", "rows": [{"label": "Append", "identity": "Append"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=15", "label": "EXPLAIN"}, {"url": "/docs/15/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/15/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/enable_parallel_append/?v=15", "label": "enable_parallel_append"}, {"url": "/wiki/guc/enable_async_append/?v=15", "label": "enable_async_append"}], "release": {"ref": "PostgreSQL 15.19 source archive", "label": "15.19", "major": "15", "channel": "stable", "revision": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89", "source_url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "line": 1199, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1199", "sha256": "bb3b442d0f1b098aa8707335250102f027a596cd94117308bd16d1d36b258f5c", "archive_sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89"}, {"url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "line": 181, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:181", "sha256": "19836c50a272741a4eac653541e655437c2e00710a541e5348d6a277d0669d7c", "archive_sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89"}, {"url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "bf508a0efe0cd78f222a6994773b2095f744155ea12935e7fde95b60321393ce", "archive_sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89"}, {"url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "fb4a4c8165495299131173680bc02a950d88e1ff610231fd97997bc0c9afc1d7", "archive_sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89"}, {"url": "https://pg.center/docs/15/using-explain.html#USING-EXPLAIN-CAVEATS", "path": "using-explain.html", "label": "PostgreSQL 15.19 \u00b7 using-explain", "sha256": "d1f509457c647da453d2575c772d91022a0f115dd84f9a3b20f5ff25a243648f", "language": "en", "original_url": "/docs/15/using-explain.html#USING-EXPLAIN-CAVEATS"}, {"url": "https://pg.center/docs/15/parallel-plans.html#PARALLEL-APPEND", "path": "parallel-plans.html", "label": "PostgreSQL 15.19 \u00b7 parallel-plans", "sha256": "ec9345488a15cdc05d3e0b0849763e2bf0b864ad17de786c5f023db5dab1ea96", "language": "en", "original_url": "/docs/15/parallel-plans.html#PARALLEL-APPEND"}, {"url": "https://pg.center/docs/15/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 15.19 \u00b7 using-explain", "sha256": "d1f509457c647da453d2575c772d91022a0f115dd84f9a3b20f5ff25a243648f", "language": "en", "original_url": "/docs/15/using-explain.html#USING-EXPLAIN-ANALYZE"}], "node_tag": "T_Append", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aAppend.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1aExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM."]}, {"title": "\u540c\u7248\u672c\u624b\u518c\u8bf4\u660e", "paragraphs": ["\u901a\u5e38 EXPLAIN \u663e\u793a\u89c4\u5212\u5668\u521b\u5efa\u7684\u6bcf\u4e2a\u8282\u70b9\u3002\u4f46\u6267\u884c\u5668\u6709\u65f6\u53ef\u4ee5\u6839\u636e\u89c4\u5212\u9636\u6bb5\u5c1a\u4e0d\u53ef\u77e5\u7684\u53c2\u6570\u503c\uff0c\u5224\u5b9a\u67d0\u4e9b\u8282\u70b9\u65e0\u6cd5\u4ea7\u751f\u4efb\u4f55\u884c\uff0c\u56e0\u6b64\u4e0d\u5fc5\u6267\u884c\u3002\uff08\u76ee\u524d\u4ec5\u4f1a\u53d1\u751f\u5728\u626b\u63cf\u5206\u533a\u8868\u7684 Append \u6216 MergeAppend \u8282\u70b9\u7684\u5b50\u8282\u70b9\u4e0a\u3002\uff09\u6b64\u65f6 EXPLAIN \u7701\u7565\u8fd9\u4e9b\u8282\u70b9\uff0c\u6539\u4e3a\u663e\u793a Subplans Removed: N\u3002", "\u6bcf\u5f53 PostgreSQL \u9700\u8981\u5c06\u6765\u81ea\u591a\u4e2a\u6e90\u7684\u884c\u5408\u5e76\u6210\u4e00\u4e2a\u7ed3\u679c\u96c6\u65f6\uff0c\u5b83\u5c31\u4f1a\u4f7f\u7528 Append \u6216 MergeAppend \u8ba1\u5212\u8282\u70b9\u3002\u8fd9\u79cd\u60c5\u51b5\u5e38\u89c1\u4e8e\u5b9e\u73b0 UNION ALL \u6216\u626b\u63cf\u5206\u533a\u8868\u65f6\u3002\u8fd9\u6837\u7684\u8282\u70b9\u548c\u5176\u4ed6\u4efb\u4f55\u8ba1\u5212\u4e2d\u7684\u60c5\u5f62\u4e00\u6837\uff0c\u4e5f\u53ef\u4ee5\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u3002\u4e0d\u8fc7\uff0c\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\uff0c\u89c4\u5212\u5668\u4e5f\u53ef\u80fd\u6539\u7528 Parallel Append \u8282\u70b9\u3002", "\u5f53 Append \u8282\u70b9\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u65f6\uff0c\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u4f1a\u6309\u7167\u5b50\u8ba1\u5212\u51fa\u73b0\u7684\u987a\u5e8f\u6267\u884c\u5b83\u4eec\uff0c\u56e0\u6b64\u6240\u6709\u53c2\u4e0e\u8fdb\u7a0b\u4f1a\u534f\u4f5c\u6267\u884c\u7b2c\u4e00\u4e2a\u5b50\u8ba1\u5212\u76f4\u5230\u5176\u5b8c\u6210\uff0c\u7136\u540e\u518d\u5927\u81f4\u540c\u65f6\u8f6c\u5411\u7b2c\u4e8c\u4e2a\u5b50\u8ba1\u5212\u3002\u800c\u5f53\u4f7f\u7528 Parallel Append \u65f6\uff0c\u6267\u884c\u5668\u4f1a\u5c3d\u53ef\u80fd\u5747\u5300\u5730\u5c06\u53c2\u4e0e\u8fdb\u7a0b\u5206\u6563\u5230\u5404\u4e2a\u5b50\u8ba1\u5212\u4e0a\uff0c\u4ece\u800c\u4f7f\u591a\u4e2a\u5b50\u8ba1\u5212\u80fd\u591f\u540c\u65f6\u6267\u884c\u3002\u8fd9\u6837\u65e2\u907f\u514d\u4e86\u4e89\u7528\uff0c\u4e5f\u907f\u514d\u8ba9\u90a3\u4e9b\u4ece\u672a\u6267\u884c\u67d0\u4e2a\u5b50\u8ba1\u5212\u7684\u8fdb\u7a0b\u627f\u62c5\u5176\u542f\u52a8\u4ee3\u4ef7\u3002", "\u6b64\u5916\uff0c\u4e0e\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\u53ea\u80fd\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\u7684\u666e\u901a Append \u8282\u70b9\u4e0d\u540c\uff0cParallel Append \u8282\u70b9\u65e2\u53ef\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\uff0c\u4e5f\u53ef\u5305\u542b\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u3002\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u53ea\u7531\u4e00\u4e2a\u8fdb\u7a0b\u626b\u63cf\uff0c\u56e0\u4e3a\u591a\u6b21\u626b\u63cf\u4f1a\u4ea7\u751f\u91cd\u590d\u7ed3\u679c\u3002\u56e0\u6b64\uff0c\u5373\u4f7f\u6ca1\u6709\u9ad8\u6548\u7684\u90e8\u5206\u8ba1\u5212\uff0c\u62fc\u63a5\u591a\u4e2a\u7ed3\u679c\u96c6\u7684\u8ba1\u5212\u4e5f\u80fd\u5b9e\u73b0\u7c97\u7c92\u5ea6\u5e76\u884c\u3002\u4f8b\u5982\uff0c\u9488\u5bf9\u5206\u533a\u8868\u7684\u67e5\u8be2\uff0c\u53ef\u80fd\u53ea\u6709\u501f\u52a9\u4e0d\u652f\u6301\u5e76\u884c\u626b\u63cf\u7684\u7d22\u5f15\u624d\u80fd\u9ad8\u6548\u6267\u884c\u3002\u89c4\u5212\u5668\u53ef\u80fd\u9009\u62e9\u4f7f\u7528 Parallel Append \u62fc\u63a5\u591a\u4e2a\u666e\u901a Index Scan \u8ba1\u5212\uff1b\u6bcf\u6b21\u7d22\u5f15\u626b\u63cf\u90fd\u5fc5\u987b\u7531\u5355\u4e2a\u8fdb\u7a0b\u5b8c\u6574\u6267\u884c\uff0c\u4f46\u4e0d\u540c\u626b\u63cf\u53ef\u4ee5\u7531\u4e0d\u540c\u8fdb\u7a0b\u540c\u65f6\u6267\u884c\u3002"]}, {"title": "\u672c\u7248\u624b\u518c\u4e2d\u7684\u793a\u4f8b", "blocks": [{"code": "EXPLAIN UPDATE parent SET f2 = f2 + 1 WHERE f1 = 101;\n                                              QUERY PLAN\n------------------------------------------------------------------------------------------------------\n Update on parent  (cost=0.00..24.59 rows=0 width=0)\n   Update on parent parent_1\n   Update on child1 parent_2\n   Update on child2 parent_3\n   Update on child3 parent_4\n   ->  Result  (cost=0.00..24.59 rows=4 width=14)\n         ->  Append  (cost=0.00..24.54 rows=4 width=14)\n               ->  Seq Scan on parent parent_1  (cost=0.00..0.00 rows=1 width=14)\n                     Filter: (f1 = 101)\n               ->  Index Scan using child1_pkey on child1 parent_2  (cost=0.15..8.17 rows=1 width=14)\n                     Index Cond: (f1 = 101)\n               ->  Index Scan using child2_pkey on child2 parent_3  (cost=0.15..8.17 rows=1 width=14)\n                     Index Cond: (f1 = 101)\n               ->  Index Scan using child3_pkey on child3 parent_4  (cost=0.15..8.17 rows=1 width=14)\n                     Index Cond: (f1 = 101)", "source": {"url": "/docs/15/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 15.19 \u00b7 using-explain", "sha256": "d1f509457c647da453d2575c772d91022a0f115dd84f9a3b20f5ff25a243648f"}, "paragraphs": ["\u793a\u4f8b\u6458\u81ea PostgreSQL 15.19 \u624b\u518c\uff1b\u672c\u767e\u79d1\u672a\u5b9e\u9645\u6267\u884c\u6b64\u793a\u4f8b\u3002", "UPDATE\u3001DELETE \u6216 MERGE \u4f5c\u7528\u4e8e\u7ee7\u627f\u5c42\u7ea7\u65f6\uff0c\u8f93\u51fa\u53ef\u80fd\u5982\u4e0b\uff1a"]}]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["\u8bf4\u660e\uff1a\u6bcf\u4e2a Append \u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5fc5\u987b\u9010\u4e00\u5904\u7406\u7684\u5b50\u8ba1\u5212\uff0c\u65b9\u5411\u53ef\u4ee5\u6b63\u5411\u6216\u53cd\u5411\u3002\u6267\u884c\u7b2c whichplan \u4e2a\u5b50\u8ba1\u5212\u53d6\u56de\u5143\u7ec4\uff0c\u76f4\u5230\u5b83\u4e0d\u518d\u8fd4\u56de\u5143\u7ec4\uff0c\u7136\u540e\u5173\u95ed\u8be5\u8ba1\u5212\u5e76\u542f\u52a8\u4e0b\u4e00\u4e2a\u3002", "Append \u8282\u70b9\u4e0d\u4f7f\u7528\u5de6\u3001\u53f3\u5b50\u6811\uff0c\u800c\u662f\u7ef4\u62a4\u4e00\u4e2a\u5b50\u8ba1\u5212\u5217\u8868\uff0c\u56e0\u6b64\u5178\u578b\u7684 Append \u8282\u70b9\u5728\u8ba1\u5212\u6811\u4e2d\u5982\u4e0b\u6240\u793a\uff1a", "... / Append -------+------+------+--- nil / \\ | | | nil nil ... ... ... subplans", "Append \u8282\u70b9\u76ee\u524d\u7528\u4e8e\u5e76\u96c6\u64cd\u4f5c\uff0c\u4e5f\u7528\u4e8e\u9700\u8981\u626b\u63cf\u591a\u4e2a\u5173\u7cfb\u7684\u7ee7\u627f\u67e5\u8be2\u3002\u4f8b\u5982\uff0c\u5728\u6807\u51c6\u7684 person/student/employee/student-emp \u793a\u4f8b\u4e2d\uff0cstudent \u548c employee \u7ee7\u627f\u81ea person\uff0c\u800c student-emp \u540c\u65f6\u7ee7\u627f\u81ea student \u548c employee\uff0c\u67e5\u8be2\u5982\u4e0b\uff1a", "| Append -------+-------+--------+--------+ / \\ | | | | nil nil Scan Scan Scan Scan | | | | person employee student student-emp"]}, {"code": "case T_Append:\n\t\t\tpname = sname = \"Append\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u904d\u5386\u5404\u5b50\u8ba1\u5212\u5e76\u5408\u5e76\u5176\u8f93\u51fa\u884c\u3002"], "localization": {"status": "complete", "sources": [{"url": "/docs/15/parallel-plans.html", "method": "same-major semantic node", "sha256": "f854eb236b7b7015acb3d4356b2199700ef6396672fbb271f4325b656c16e6c3", "language": "zh", "matched_nodes": ["#PARALLEL-PLANS/div[6]/p[1]", "#PARALLEL-PLANS/div[6]/p[2]"]}], "language": "zh", "original_text": {"/versions/15/description/0": "Visits its child plans and combines their rows.", "/versions/15/facts/0/label": "Core node tag", "/versions/15/facts/1/label": "Structured EXPLAIN Node Type", "/versions/15/facts/2/label": "Inputs", "/versions/15/facts/2/value": "Multiple child plans", "/versions/15/facts/3/label": "Output", "/versions/15/facts/3/value": "Combined tuples", "/versions/15/facts/4/label": "Executor initializer", "/versions/15/facts/5/label": "Memory mechanism", "/versions/15/tables/0/title": "EXPLAIN labels in this source build", "/versions/15/related/1/label": "Using EXPLAIN", "/versions/15/related/2/label": "Parallel plans", "/versions/15/sections/0/title": "EXPLAIN names and attributes", "/versions/15/sections/1/title": "Memory and temporary storage", "/versions/15/sections/2/title": "Parallel execution and instrumentation", "/versions/15/sections/3/title": "Same-version manual discussion", "/versions/15/sections/4/title": "Examples from this manual build", "/versions/15/sections/5/title": "Executor implementation notes", "/versions/15/sections/6/title": "EXPLAIN identity in core source", "/versions/15/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.", "/versions/15/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/15/sections/0/paragraphs/1": "Text names recorded by this source: Append.", "/versions/15/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/15/sections/1/paragraphs/0": "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.", "/versions/15/sections/2/paragraphs/0": "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.", "/versions/15/sections/2/paragraphs/1": "Callbacks in this build: ExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM.", "/versions/15/sections/3/paragraphs/0": "Normally, EXPLAIN will display every plan node created by the planner. However, there are cases where the executor can determine that certain nodes need not be executed because they cannot produce any rows, based on parameter values that were not available at planning time. (Currently this can only happen for child nodes of an Append or MergeAppend node that is scanning a partitioned table.) When this happens, those plan nodes are omitted from the EXPLAIN output and a Subplans Removed: N annotation appears instead.", "/versions/15/sections/3/paragraphs/1": "Whenever PostgreSQL needs to combine rows from multiple sources into a single result set, it uses an Append or MergeAppend plan node. This commonly happens when implementing UNION ALL or when scanning a partitioned table. Such nodes can be used in parallel plans just as they can in any other plan. However, in a parallel plan, the planner may instead use a Parallel Append node.", "/versions/15/sections/3/paragraphs/2": "When an Append node is used in a parallel plan, each process will execute the child plans in the order in which they appear, so that all participating processes cooperate to execute the first child plan until it is complete and then move to the second plan at around the same time. When a Parallel Append is used instead, the executor will instead spread out the participating processes as evenly as possible across its child plans, so that multiple child plans are executed simultaneously. This avoids contention, and also avoids paying the startup cost of a child plan in those processes that never execute it.", "/versions/15/sections/3/paragraphs/3": "Also, unlike a regular Append node, which can only have partial children when used within a parallel plan, a Parallel Append node can have both partial and non-partial child plans. Non-partial children will be scanned by only a single process, since scanning them more than once would produce duplicate results. Plans that involve appending multiple results sets can therefore achieve coarse-grained parallelism even when efficient partial plans are not available. For example, consider a query against a partitioned table that can only be implemented efficiently by using an index that does not support parallel scans. The planner might choose a Parallel Append of regular Index Scan plans; each individual index scan would have to be executed to completion by a single process, but different scans could be performed at the same time by different processes.", "/versions/15/sections/5/paragraphs/0": "NOTES Each append node contains a list of one or more subplans which must be iteratively processed (forwards or backwards). Tuples are retrieved by executing the 'whichplan'th subplan until the subplan stops returning tuples, at which point that plan is shut down and the next started up.", "/versions/15/sections/5/paragraphs/1": "Append nodes don't make use of their left and right subtrees, rather they maintain a list of subplans so a typical append node looks like this in the plan tree:", "/versions/15/sections/5/paragraphs/3": "Append nodes are currently used for unions, and to support inheritance queries, where several relations need to be scanned. For example, in our standard person/student/employee/student-emp example, where student and employee inherit from person and student-emp inherits from student and employee, the query:", "/versions/15/tables/0/columns/0/label": "Text-format label", "/versions/15/tables/0/columns/1/label": "Structured node identity", "/versions/15/sections/4/blocks/0/paragraphs/0": "Example copied from the PostgreSQL 15.19 manual; it was not executed for this collection.", "/versions/15/sections/4/blocks/0/paragraphs/1": "When an UPDATE , DELETE , or MERGE command affects an inheritance hierarchy, the output might look like this:"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "0d9d344bb93eb0d19a9cb5a14c442575ee67aa2466a1618df6ffe3a4a0d24fc4"}, "evidence_kind": "source and documentation", "explain_names": ["Append"], "partial_modes": [], "comparison_data": {"node_tag": "T_Append", "strategies": [], "text_names": ["Append"], "initializer": "ExecInitAppend", "partial_modes": [], "memory_mechanism": "unclassified", "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "comparison_hash": "05fc087ef5a99b9d2d14f9b7e397d941085dafd8c263de24871ec9926b47ad8f", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeAppend.c"}, "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "16": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_Append"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "Append"}, {"label": "\u8f93\u5165", "value": "\u591a\u4e2a\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5408\u5e76\u540e\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitAppend"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "unclassified"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "3d188cb53737b7388ee195ec9de06c9edf83a6dca24cedb1c9d65f3c3bbcc349", "archive_sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed"}], "mechanism": "unclassified", "description": "\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002", "source_notes": []}, "tables": [{"key": "explain-labels", "rows": [{"label": "Append", "identity": "Append"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=16", "label": "EXPLAIN"}, {"url": "/docs/16/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/16/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/enable_parallel_append/?v=16", "label": "enable_parallel_append"}, {"url": "/wiki/guc/enable_async_append/?v=16", "label": "enable_async_append"}], "release": {"ref": "PostgreSQL 16.15 source archive", "label": "16.15", "major": "16", "channel": "stable", "revision": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed", "source_url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "line": 1232, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1232", "sha256": "8e017f0116dbea471339b40c37a667cc9f95039e7e0329c783e5e8ce194de7e1", "archive_sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed"}, {"url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "line": 181, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:181", "sha256": "e48c08e555f8cb4e4bb43df516c4b8906ce9bc374b2a745d98a1fc8c22cc5099", "archive_sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed"}, {"url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "3d188cb53737b7388ee195ec9de06c9edf83a6dca24cedb1c9d65f3c3bbcc349", "archive_sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed"}, {"url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "97db47353db76326b874589a5ad0a04501cc74cd72e237e7bd956e7472c41f1f", "archive_sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed"}, {"url": "https://pg.center/docs/16/using-explain.html#USING-EXPLAIN-CAVEATS", "path": "using-explain.html", "label": "PostgreSQL 16.15 \u00b7 using-explain", "sha256": "bd8b86e5281cf0e52ad6e0e4bb8b6ff6510dac61982b44f0c1dd07d54012db3c", "language": "en", "original_url": "/docs/16/using-explain.html#USING-EXPLAIN-CAVEATS"}, {"url": "https://pg.center/docs/16/parallel-plans.html#PARALLEL-APPEND", "path": "parallel-plans.html", "label": "PostgreSQL 16.15 \u00b7 parallel-plans", "sha256": "53d83f63f97381fe1e4c0cfe5ceb81d30c1542b03e35a144684afd8fb3b9686c", "language": "en", "original_url": "/docs/16/parallel-plans.html#PARALLEL-APPEND"}, {"url": "https://pg.center/docs/16/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 16.15 \u00b7 using-explain", "sha256": "bd8b86e5281cf0e52ad6e0e4bb8b6ff6510dac61982b44f0c1dd07d54012db3c", "language": "en", "original_url": "/docs/16/using-explain.html#USING-EXPLAIN-ANALYZE"}], "node_tag": "T_Append", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aAppend.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1aExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM."]}, {"title": "\u540c\u7248\u672c\u624b\u518c\u8bf4\u660e", "paragraphs": ["\u901a\u5e38 EXPLAIN \u663e\u793a\u89c4\u5212\u5668\u521b\u5efa\u7684\u6bcf\u4e2a\u8282\u70b9\u3002\u4f46\u6267\u884c\u5668\u6709\u65f6\u53ef\u4ee5\u6839\u636e\u89c4\u5212\u9636\u6bb5\u5c1a\u4e0d\u53ef\u77e5\u7684\u53c2\u6570\u503c\uff0c\u5224\u5b9a\u67d0\u4e9b\u8282\u70b9\u65e0\u6cd5\u4ea7\u751f\u4efb\u4f55\u884c\uff0c\u56e0\u6b64\u4e0d\u5fc5\u6267\u884c\u3002\uff08\u76ee\u524d\u4ec5\u4f1a\u53d1\u751f\u5728\u626b\u63cf\u5206\u533a\u8868\u7684 Append \u6216 MergeAppend \u8282\u70b9\u7684\u5b50\u8282\u70b9\u4e0a\u3002\uff09\u6b64\u65f6 EXPLAIN \u7701\u7565\u8fd9\u4e9b\u8282\u70b9\uff0c\u6539\u4e3a\u663e\u793a Subplans Removed: N\u3002", "\u6bcf\u5f53 PostgreSQL \u9700\u8981\u5c06\u6765\u81ea\u591a\u4e2a\u6e90\u7684\u884c\u5408\u5e76\u6210\u4e00\u4e2a\u7ed3\u679c\u96c6\u65f6\uff0c\u5b83\u5c31\u4f1a\u4f7f\u7528 Append \u6216 MergeAppend \u8ba1\u5212\u8282\u70b9\u3002\u8fd9\u79cd\u60c5\u51b5\u5e38\u89c1\u4e8e\u5b9e\u73b0 UNION ALL \u6216\u626b\u63cf\u5206\u533a\u8868\u65f6\u3002\u8fd9\u6837\u7684\u8282\u70b9\u548c\u5176\u4ed6\u4efb\u4f55\u8ba1\u5212\u4e2d\u7684\u60c5\u5f62\u4e00\u6837\uff0c\u4e5f\u53ef\u4ee5\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u3002\u4e0d\u8fc7\uff0c\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\uff0c\u89c4\u5212\u5668\u4e5f\u53ef\u80fd\u6539\u7528 Parallel Append \u8282\u70b9\u3002", "\u5f53 Append \u8282\u70b9\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u65f6\uff0c\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u4f1a\u6309\u7167\u5b50\u8ba1\u5212\u51fa\u73b0\u7684\u987a\u5e8f\u6267\u884c\u5b83\u4eec\uff0c\u56e0\u6b64\u6240\u6709\u53c2\u4e0e\u8fdb\u7a0b\u4f1a\u534f\u4f5c\u6267\u884c\u7b2c\u4e00\u4e2a\u5b50\u8ba1\u5212\u76f4\u5230\u5176\u5b8c\u6210\uff0c\u7136\u540e\u518d\u5927\u81f4\u540c\u65f6\u8f6c\u5411\u7b2c\u4e8c\u4e2a\u5b50\u8ba1\u5212\u3002\u800c\u5f53\u4f7f\u7528 Parallel Append \u65f6\uff0c\u6267\u884c\u5668\u4f1a\u5c3d\u53ef\u80fd\u5747\u5300\u5730\u5c06\u53c2\u4e0e\u8fdb\u7a0b\u5206\u6563\u5230\u5404\u4e2a\u5b50\u8ba1\u5212\u4e0a\uff0c\u4ece\u800c\u4f7f\u591a\u4e2a\u5b50\u8ba1\u5212\u80fd\u591f\u540c\u65f6\u6267\u884c\u3002\u8fd9\u6837\u65e2\u907f\u514d\u4e86\u4e89\u7528\uff0c\u4e5f\u907f\u514d\u8ba9\u90a3\u4e9b\u4ece\u672a\u6267\u884c\u67d0\u4e2a\u5b50\u8ba1\u5212\u7684\u8fdb\u7a0b\u627f\u62c5\u5176\u542f\u52a8\u4ee3\u4ef7\u3002", "\u6b64\u5916\uff0c\u4e0e\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\u53ea\u80fd\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\u7684\u666e\u901a Append \u8282\u70b9\u4e0d\u540c\uff0cParallel Append \u8282\u70b9\u65e2\u53ef\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\uff0c\u4e5f\u53ef\u5305\u542b\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u3002\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u53ea\u7531\u4e00\u4e2a\u8fdb\u7a0b\u626b\u63cf\uff0c\u56e0\u4e3a\u591a\u6b21\u626b\u63cf\u4f1a\u4ea7\u751f\u91cd\u590d\u7ed3\u679c\u3002\u56e0\u6b64\uff0c\u5373\u4f7f\u6ca1\u6709\u9ad8\u6548\u7684\u90e8\u5206\u8ba1\u5212\uff0c\u62fc\u63a5\u591a\u4e2a\u7ed3\u679c\u96c6\u7684\u8ba1\u5212\u4e5f\u80fd\u5b9e\u73b0\u7c97\u7c92\u5ea6\u5e76\u884c\u3002\u4f8b\u5982\uff0c\u9488\u5bf9\u5206\u533a\u8868\u7684\u67e5\u8be2\uff0c\u53ef\u80fd\u53ea\u6709\u501f\u52a9\u4e0d\u652f\u6301\u5e76\u884c\u626b\u63cf\u7684\u7d22\u5f15\u624d\u80fd\u9ad8\u6548\u6267\u884c\u3002\u89c4\u5212\u5668\u53ef\u80fd\u9009\u62e9\u4f7f\u7528 Parallel Append \u62fc\u63a5\u591a\u4e2a\u666e\u901a Index Scan \u8ba1\u5212\uff1b\u6bcf\u6b21\u7d22\u5f15\u626b\u63cf\u90fd\u5fc5\u987b\u7531\u5355\u4e2a\u8fdb\u7a0b\u5b8c\u6574\u6267\u884c\uff0c\u4f46\u4e0d\u540c\u626b\u63cf\u53ef\u4ee5\u7531\u4e0d\u540c\u8fdb\u7a0b\u540c\u65f6\u6267\u884c\u3002"]}, {"title": "\u672c\u7248\u624b\u518c\u4e2d\u7684\u793a\u4f8b", "blocks": [{"code": "EXPLAIN UPDATE parent SET f2 = f2 + 1 WHERE f1 = 101;\n                                              QUERY PLAN\n------------------------------------------------------------------------------------------------------\n Update on parent  (cost=0.00..24.59 rows=0 width=0)\n   Update on parent parent_1\n   Update on child1 parent_2\n   Update on child2 parent_3\n   Update on child3 parent_4\n   ->  Result  (cost=0.00..24.59 rows=4 width=14)\n         ->  Append  (cost=0.00..24.54 rows=4 width=14)\n               ->  Seq Scan on parent parent_1  (cost=0.00..0.00 rows=1 width=14)\n                     Filter: (f1 = 101)\n               ->  Index Scan using child1_pkey on child1 parent_2  (cost=0.15..8.17 rows=1 width=14)\n                     Index Cond: (f1 = 101)\n               ->  Index Scan using child2_pkey on child2 parent_3  (cost=0.15..8.17 rows=1 width=14)\n                     Index Cond: (f1 = 101)\n               ->  Index Scan using child3_pkey on child3 parent_4  (cost=0.15..8.17 rows=1 width=14)\n                     Index Cond: (f1 = 101)", "source": {"url": "/docs/16/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 16.15 \u00b7 using-explain", "sha256": "bd8b86e5281cf0e52ad6e0e4bb8b6ff6510dac61982b44f0c1dd07d54012db3c"}, "paragraphs": ["\u793a\u4f8b\u6458\u81ea PostgreSQL 16.15 \u624b\u518c\uff1b\u672c\u767e\u79d1\u672a\u5b9e\u9645\u6267\u884c\u6b64\u793a\u4f8b\u3002", "UPDATE\u3001DELETE \u6216 MERGE \u4f5c\u7528\u4e8e\u7ee7\u627f\u5c42\u7ea7\u65f6\uff0c\u8f93\u51fa\u53ef\u80fd\u5982\u4e0b\uff1a"]}]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["\u8bf4\u660e\uff1a\u6bcf\u4e2a Append \u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5fc5\u987b\u9010\u4e00\u5904\u7406\u7684\u5b50\u8ba1\u5212\uff0c\u65b9\u5411\u53ef\u4ee5\u6b63\u5411\u6216\u53cd\u5411\u3002\u6267\u884c\u7b2c whichplan \u4e2a\u5b50\u8ba1\u5212\u53d6\u56de\u5143\u7ec4\uff0c\u76f4\u5230\u5b83\u4e0d\u518d\u8fd4\u56de\u5143\u7ec4\uff0c\u7136\u540e\u5173\u95ed\u8be5\u8ba1\u5212\u5e76\u542f\u52a8\u4e0b\u4e00\u4e2a\u3002", "Append \u8282\u70b9\u4e0d\u4f7f\u7528\u5de6\u3001\u53f3\u5b50\u6811\uff0c\u800c\u662f\u7ef4\u62a4\u4e00\u4e2a\u5b50\u8ba1\u5212\u5217\u8868\uff0c\u56e0\u6b64\u5178\u578b\u7684 Append \u8282\u70b9\u5728\u8ba1\u5212\u6811\u4e2d\u5982\u4e0b\u6240\u793a\uff1a", "... / Append -------+------+------+--- nil / \\ | | | nil nil ... ... ... subplans", "Append \u8282\u70b9\u76ee\u524d\u7528\u4e8e\u5e76\u96c6\u64cd\u4f5c\uff0c\u4e5f\u7528\u4e8e\u9700\u8981\u626b\u63cf\u591a\u4e2a\u5173\u7cfb\u7684\u7ee7\u627f\u67e5\u8be2\u3002\u4f8b\u5982\uff0c\u5728\u6807\u51c6\u7684 person/student/employee/student-emp \u793a\u4f8b\u4e2d\uff0cstudent \u548c employee \u7ee7\u627f\u81ea person\uff0c\u800c student-emp \u540c\u65f6\u7ee7\u627f\u81ea student \u548c employee\uff0c\u67e5\u8be2\u5982\u4e0b\uff1a", "| Append -------+-------+--------+--------+ / \\ | | | | nil nil Scan Scan Scan Scan | | | | person employee student student-emp"]}, {"code": "case T_Append:\n\t\t\tpname = sname = \"Append\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u904d\u5386\u5404\u5b50\u8ba1\u5212\u5e76\u5408\u5e76\u5176\u8f93\u51fa\u884c\u3002"], "localization": {"status": "complete", "sources": [{"url": "/docs/16/parallel-plans.html", "method": "same-major semantic node", "sha256": "ebdab5889ade652e62c92fd2e4361d8aa32ae8132faccfdcafab869292fc4392", "language": "zh", "matched_nodes": ["#PARALLEL-PLANS/div[6]/p[1]", "#PARALLEL-PLANS/div[6]/p[2]"]}], "language": "zh", "original_text": {"/versions/16/description/0": "Visits its child plans and combines their rows.", "/versions/16/facts/0/label": "Core node tag", "/versions/16/facts/1/label": "Structured EXPLAIN Node Type", "/versions/16/facts/2/label": "Inputs", "/versions/16/facts/2/value": "Multiple child plans", "/versions/16/facts/3/label": "Output", "/versions/16/facts/3/value": "Combined tuples", "/versions/16/facts/4/label": "Executor initializer", "/versions/16/facts/5/label": "Memory mechanism", "/versions/16/tables/0/title": "EXPLAIN labels in this source build", "/versions/16/related/1/label": "Using EXPLAIN", "/versions/16/related/2/label": "Parallel plans", "/versions/16/sections/0/title": "EXPLAIN names and attributes", "/versions/16/sections/1/title": "Memory and temporary storage", "/versions/16/sections/2/title": "Parallel execution and instrumentation", "/versions/16/sections/3/title": "Same-version manual discussion", "/versions/16/sections/4/title": "Examples from this manual build", "/versions/16/sections/5/title": "Executor implementation notes", "/versions/16/sections/6/title": "EXPLAIN identity in core source", "/versions/16/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.", "/versions/16/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/16/sections/0/paragraphs/1": "Text names recorded by this source: Append.", "/versions/16/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/16/sections/1/paragraphs/0": "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.", "/versions/16/sections/2/paragraphs/0": "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.", "/versions/16/sections/2/paragraphs/1": "Callbacks in this build: ExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM.", "/versions/16/sections/3/paragraphs/0": "Normally, EXPLAIN will display every plan node created by the planner. However, there are cases where the executor can determine that certain nodes need not be executed because they cannot produce any rows, based on parameter values that were not available at planning time. (Currently this can only happen for child nodes of an Append or MergeAppend node that is scanning a partitioned table.) When this happens, those plan nodes are omitted from the EXPLAIN output and a Subplans Removed: N annotation appears instead.", "/versions/16/sections/3/paragraphs/1": "Whenever PostgreSQL needs to combine rows from multiple sources into a single result set, it uses an Append or MergeAppend plan node. This commonly happens when implementing UNION ALL or when scanning a partitioned table. Such nodes can be used in parallel plans just as they can in any other plan. However, in a parallel plan, the planner may instead use a Parallel Append node.", "/versions/16/sections/3/paragraphs/2": "When an Append node is used in a parallel plan, each process will execute the child plans in the order in which they appear, so that all participating processes cooperate to execute the first child plan until it is complete and then move to the second plan at around the same time. When a Parallel Append is used instead, the executor will instead spread out the participating processes as evenly as possible across its child plans, so that multiple child plans are executed simultaneously. This avoids contention, and also avoids paying the startup cost of a child plan in those processes that never execute it.", "/versions/16/sections/3/paragraphs/3": "Also, unlike a regular Append node, which can only have partial children when used within a parallel plan, a Parallel Append node can have both partial and non-partial child plans. Non-partial children will be scanned by only a single process, since scanning them more than once would produce duplicate results. Plans that involve appending multiple results sets can therefore achieve coarse-grained parallelism even when efficient partial plans are not available. For example, consider a query against a partitioned table that can only be implemented efficiently by using an index that does not support parallel scans. The planner might choose a Parallel Append of regular Index Scan plans; each individual index scan would have to be executed to completion by a single process, but different scans could be performed at the same time by different processes.", "/versions/16/sections/5/paragraphs/0": "NOTES Each append node contains a list of one or more subplans which must be iteratively processed (forwards or backwards). Tuples are retrieved by executing the 'whichplan'th subplan until the subplan stops returning tuples, at which point that plan is shut down and the next started up.", "/versions/16/sections/5/paragraphs/1": "Append nodes don't make use of their left and right subtrees, rather they maintain a list of subplans so a typical append node looks like this in the plan tree:", "/versions/16/sections/5/paragraphs/3": "Append nodes are currently used for unions, and to support inheritance queries, where several relations need to be scanned. For example, in our standard person/student/employee/student-emp example, where student and employee inherit from person and student-emp inherits from student and employee, the query:", "/versions/16/tables/0/columns/0/label": "Text-format label", "/versions/16/tables/0/columns/1/label": "Structured node identity", "/versions/16/sections/4/blocks/0/paragraphs/0": "Example copied from the PostgreSQL 16.15 manual; it was not executed for this collection.", "/versions/16/sections/4/blocks/0/paragraphs/1": "When an UPDATE , DELETE , or MERGE command affects an inheritance hierarchy, the output might look like this:"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "a9b4780bec05f2b57af90387ae423c199fa62cdeac2cfbe961313601e9f8e19c"}, "evidence_kind": "source and documentation", "explain_names": ["Append"], "partial_modes": [], "comparison_data": {"node_tag": "T_Append", "strategies": [], "text_names": ["Append"], "initializer": "ExecInitAppend", "partial_modes": [], "memory_mechanism": "unclassified", "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "comparison_hash": "05fc087ef5a99b9d2d14f9b7e397d941085dafd8c263de24871ec9926b47ad8f", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeAppend.c"}, "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "17": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_Append"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "Append"}, {"label": "\u8f93\u5165", "value": "\u591a\u4e2a\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5408\u5e76\u540e\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitAppend"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "unclassified"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "5bed8a17f6b31b143cec3ebc6cd45f1294eeab5d064bbcd434ab059e6fadc73c", "archive_sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979"}], "mechanism": "unclassified", "description": "\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002", "source_notes": []}, "tables": [{"key": "explain-labels", "rows": [{"label": "Append", "identity": "Append"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=17", "label": "EXPLAIN"}, {"url": "/docs/17/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/17/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/enable_parallel_append/?v=17", "label": "enable_parallel_append"}, {"url": "/wiki/guc/enable_async_append/?v=17", "label": "enable_async_append"}], "release": {"ref": "PostgreSQL 17.11 source archive", "label": "17.11", "major": "17", "channel": "stable", "revision": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979", "source_url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "line": 1421, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1421", "sha256": "741251b1a3b6d269a52a673d42eb63b02e13a5872db7b359b137086ab21b63c8", "archive_sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979"}, {"url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "line": 181, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:181", "sha256": "a77576e158b94cb01fa8c5174ba133004eabdd727660323f8afc66c8d2e757b8", "archive_sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979"}, {"url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "5bed8a17f6b31b143cec3ebc6cd45f1294eeab5d064bbcd434ab059e6fadc73c", "archive_sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979"}, {"url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "d390dd69e2d3f5085beb42b33e46ff0676a2959b916a12b82118a7e545f8e562", "archive_sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979"}, {"url": "https://pg.center/docs/17/using-explain.html#USING-EXPLAIN-CAVEATS", "path": "using-explain.html", "label": "PostgreSQL 17.11 \u00b7 using-explain", "sha256": "8e3422c77496cc53bfc225ccadda3e82eb23c8c362b8eb95e7fb02cdb315ea78", "language": "en", "original_url": "/docs/17/using-explain.html#USING-EXPLAIN-CAVEATS"}, {"url": "https://pg.center/docs/17/parallel-plans.html#PARALLEL-APPEND", "path": "parallel-plans.html", "label": "PostgreSQL 17.11 \u00b7 parallel-plans", "sha256": "784fe3d3b7ae7d1a34e466aa551bde484a40a3b60dc5d2ada6e1675f40713bbc", "language": "en", "original_url": "/docs/17/parallel-plans.html#PARALLEL-APPEND"}, {"url": "https://pg.center/docs/17/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 17.11 \u00b7 using-explain", "sha256": "8e3422c77496cc53bfc225ccadda3e82eb23c8c362b8eb95e7fb02cdb315ea78", "language": "en", "original_url": "/docs/17/using-explain.html#USING-EXPLAIN-ANALYZE"}], "node_tag": "T_Append", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aAppend.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1aExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM."]}, {"title": "\u540c\u7248\u672c\u624b\u518c\u8bf4\u660e", "paragraphs": ["\u901a\u5e38 EXPLAIN \u663e\u793a\u89c4\u5212\u5668\u521b\u5efa\u7684\u6bcf\u4e2a\u8282\u70b9\u3002\u4f46\u6267\u884c\u5668\u6709\u65f6\u53ef\u4ee5\u6839\u636e\u89c4\u5212\u9636\u6bb5\u5c1a\u4e0d\u53ef\u77e5\u7684\u53c2\u6570\u503c\uff0c\u5224\u5b9a\u67d0\u4e9b\u8282\u70b9\u65e0\u6cd5\u4ea7\u751f\u4efb\u4f55\u884c\uff0c\u56e0\u6b64\u4e0d\u5fc5\u6267\u884c\u3002\uff08\u76ee\u524d\u4ec5\u4f1a\u53d1\u751f\u5728\u626b\u63cf\u5206\u533a\u8868\u7684 Append \u6216 MergeAppend \u8282\u70b9\u7684\u5b50\u8282\u70b9\u4e0a\u3002\uff09\u6b64\u65f6 EXPLAIN \u7701\u7565\u8fd9\u4e9b\u8282\u70b9\uff0c\u6539\u4e3a\u663e\u793a Subplans Removed: N\u3002", "\u6bcf\u5f53 PostgreSQL \u9700\u8981\u5c06\u6765\u81ea\u591a\u4e2a\u6e90\u7684\u884c\u5408\u5e76\u6210\u4e00\u4e2a\u7ed3\u679c\u96c6\u65f6\uff0c\u5b83\u5c31\u4f1a\u4f7f\u7528 Append \u6216 MergeAppend \u8ba1\u5212\u8282\u70b9\u3002\u8fd9\u79cd\u60c5\u51b5\u5e38\u89c1\u4e8e\u5b9e\u73b0 UNION ALL \u6216\u626b\u63cf\u5206\u533a\u8868\u65f6\u3002\u8fd9\u6837\u7684\u8282\u70b9\u548c\u5176\u4ed6\u4efb\u4f55\u8ba1\u5212\u4e2d\u7684\u60c5\u5f62\u4e00\u6837\uff0c\u4e5f\u53ef\u4ee5\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u3002\u4e0d\u8fc7\uff0c\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\uff0c\u89c4\u5212\u5668\u4e5f\u53ef\u80fd\u6539\u7528 Parallel Append \u8282\u70b9\u3002", "\u5f53 Append \u8282\u70b9\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u65f6\uff0c\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u4f1a\u6309\u7167\u5b50\u8ba1\u5212\u51fa\u73b0\u7684\u987a\u5e8f\u6267\u884c\u5b83\u4eec\uff0c\u56e0\u6b64\u6240\u6709\u53c2\u4e0e\u8fdb\u7a0b\u4f1a\u534f\u4f5c\u6267\u884c\u7b2c\u4e00\u4e2a\u5b50\u8ba1\u5212\u76f4\u5230\u5176\u5b8c\u6210\uff0c\u7136\u540e\u518d\u5927\u81f4\u540c\u65f6\u8f6c\u5411\u7b2c\u4e8c\u4e2a\u5b50\u8ba1\u5212\u3002\u800c\u5f53\u4f7f\u7528 Parallel Append \u65f6\uff0c\u6267\u884c\u5668\u4f1a\u5c3d\u53ef\u80fd\u5747\u5300\u5730\u5c06\u53c2\u4e0e\u8fdb\u7a0b\u5206\u6563\u5230\u5404\u4e2a\u5b50\u8ba1\u5212\u4e0a\uff0c\u4ece\u800c\u4f7f\u591a\u4e2a\u5b50\u8ba1\u5212\u80fd\u591f\u540c\u65f6\u6267\u884c\u3002\u8fd9\u6837\u65e2\u907f\u514d\u4e86\u4e89\u7528\uff0c\u4e5f\u907f\u514d\u8ba9\u90a3\u4e9b\u4ece\u672a\u6267\u884c\u67d0\u4e2a\u5b50\u8ba1\u5212\u7684\u8fdb\u7a0b\u627f\u62c5\u5176\u542f\u52a8\u4ee3\u4ef7\u3002", "\u6b64\u5916\uff0c\u4e0e\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\u53ea\u80fd\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\u7684\u666e\u901a Append \u8282\u70b9\u4e0d\u540c\uff0cParallel Append \u8282\u70b9\u65e2\u53ef\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\uff0c\u4e5f\u53ef\u5305\u542b\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u3002\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u53ea\u7531\u4e00\u4e2a\u8fdb\u7a0b\u626b\u63cf\uff0c\u56e0\u4e3a\u591a\u6b21\u626b\u63cf\u4f1a\u4ea7\u751f\u91cd\u590d\u7ed3\u679c\u3002\u56e0\u6b64\uff0c\u5373\u4f7f\u6ca1\u6709\u9ad8\u6548\u7684\u90e8\u5206\u8ba1\u5212\uff0c\u62fc\u63a5\u591a\u4e2a\u7ed3\u679c\u96c6\u7684\u8ba1\u5212\u4e5f\u80fd\u5b9e\u73b0\u7c97\u7c92\u5ea6\u5e76\u884c\u3002\u4f8b\u5982\uff0c\u9488\u5bf9\u5206\u533a\u8868\u7684\u67e5\u8be2\uff0c\u53ef\u80fd\u53ea\u6709\u501f\u52a9\u4e0d\u652f\u6301\u5e76\u884c\u626b\u63cf\u7684\u7d22\u5f15\u624d\u80fd\u9ad8\u6548\u6267\u884c\u3002\u89c4\u5212\u5668\u53ef\u80fd\u9009\u62e9\u4f7f\u7528 Parallel Append \u62fc\u63a5\u591a\u4e2a\u666e\u901a Index Scan \u8ba1\u5212\uff1b\u6bcf\u6b21\u7d22\u5f15\u626b\u63cf\u90fd\u5fc5\u987b\u7531\u5355\u4e2a\u8fdb\u7a0b\u5b8c\u6574\u6267\u884c\uff0c\u4f46\u4e0d\u540c\u626b\u63cf\u53ef\u4ee5\u7531\u4e0d\u540c\u8fdb\u7a0b\u540c\u65f6\u6267\u884c\u3002"]}, {"title": "\u672c\u7248\u624b\u518c\u4e2d\u7684\u793a\u4f8b", "blocks": [{"code": "EXPLAIN UPDATE gtest_parent SET f1 = CURRENT_DATE WHERE f2 = 101;\n\n                                       QUERY PLAN\n----------------------------------------------------------------------------------------\n Update on gtest_parent  (cost=0.00..3.06 rows=0 width=0)\n   Update on gtest_child gtest_parent_1\n   Update on gtest_child2 gtest_parent_2\n   Update on gtest_child3 gtest_parent_3\n   ->  Append  (cost=0.00..3.06 rows=3 width=14)\n         ->  Seq Scan on gtest_child gtest_parent_1  (cost=0.00..1.01 rows=1 width=14)\n               Filter: (f2 = 101)\n         ->  Seq Scan on gtest_child2 gtest_parent_2  (cost=0.00..1.01 rows=1 width=14)\n               Filter: (f2 = 101)\n         ->  Seq Scan on gtest_child3 gtest_parent_3  (cost=0.00..1.01 rows=1 width=14)\n               Filter: (f2 = 101)", "source": {"url": "/docs/17/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 17.11 \u00b7 using-explain", "sha256": "8e3422c77496cc53bfc225ccadda3e82eb23c8c362b8eb95e7fb02cdb315ea78"}, "paragraphs": ["\u793a\u4f8b\u6458\u81ea PostgreSQL 17.11 \u624b\u518c\uff1b\u672c\u767e\u79d1\u672a\u5b9e\u9645\u6267\u884c\u6b64\u793a\u4f8b\u3002", "\u5f53 UPDATE \u3001 DELETE \u6216 MERGE \u547d\u4ee4\u5f71\u54cd\u5206\u533a\u8868\u6216\u7ee7\u627f\u5c42\u6b21\u65f6\uff0c\u8f93\u51fa\u53ef\u80fd\u50cf\u8fd9\u6837\uff1a"]}]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["\u8bf4\u660e\uff1a\u6bcf\u4e2a Append \u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5fc5\u987b\u9010\u4e00\u5904\u7406\u7684\u5b50\u8ba1\u5212\uff0c\u65b9\u5411\u53ef\u4ee5\u6b63\u5411\u6216\u53cd\u5411\u3002\u6267\u884c\u7b2c whichplan \u4e2a\u5b50\u8ba1\u5212\u53d6\u56de\u5143\u7ec4\uff0c\u76f4\u5230\u5b83\u4e0d\u518d\u8fd4\u56de\u5143\u7ec4\uff0c\u7136\u540e\u5173\u95ed\u8be5\u8ba1\u5212\u5e76\u542f\u52a8\u4e0b\u4e00\u4e2a\u3002", "Append \u8282\u70b9\u4e0d\u4f7f\u7528\u5de6\u3001\u53f3\u5b50\u6811\uff0c\u800c\u662f\u7ef4\u62a4\u4e00\u4e2a\u5b50\u8ba1\u5212\u5217\u8868\uff0c\u56e0\u6b64\u5178\u578b\u7684 Append \u8282\u70b9\u5728\u8ba1\u5212\u6811\u4e2d\u5982\u4e0b\u6240\u793a\uff1a", "... / Append -------+------+------+--- nil / \\ | | | nil nil ... ... ... subplans", "Append \u8282\u70b9\u76ee\u524d\u7528\u4e8e\u5e76\u96c6\u64cd\u4f5c\uff0c\u4e5f\u7528\u4e8e\u9700\u8981\u626b\u63cf\u591a\u4e2a\u5173\u7cfb\u7684\u7ee7\u627f\u67e5\u8be2\u3002\u4f8b\u5982\uff0c\u5728\u6807\u51c6\u7684 person/student/employee/student-emp \u793a\u4f8b\u4e2d\uff0cstudent \u548c employee \u7ee7\u627f\u81ea person\uff0c\u800c student-emp \u540c\u65f6\u7ee7\u627f\u81ea student \u548c employee\uff0c\u67e5\u8be2\u5982\u4e0b\uff1a", "| Append -------+-------+--------+--------+ / \\ | | | | nil nil Scan Scan Scan Scan | | | | person employee student student-emp"]}, {"code": "case T_Append:\n\t\t\tpname = sname = \"Append\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u904d\u5386\u5404\u5b50\u8ba1\u5212\u5e76\u5408\u5e76\u5176\u8f93\u51fa\u884c\u3002"], "localization": {"status": "complete", "sources": [{"url": "/docs/17/parallel-plans.html", "method": "same-major semantic node", "sha256": "bc44e48acadcea02ac72779d59456e07d8600160357ceacdc258da2cbc891e23", "language": "zh", "matched_nodes": ["#PARALLEL-PLANS/div[6]/p[1]", "#PARALLEL-PLANS/div[6]/p[2]"]}, {"url": "/docs/17/using-explain.html", "method": "same-major semantic node", "sha256": "610ae355c419b53a5e213a8c8e2eacbf34e4fa0ac8f6d27365071bc6d3c90278", "language": "zh", "matched_nodes": ["#USING-EXPLAIN/div[8]/p[22]"]}], "language": "zh", "original_text": {"/versions/17/description/0": "Visits its child plans and combines their rows.", "/versions/17/facts/0/label": "Core node tag", "/versions/17/facts/1/label": "Structured EXPLAIN Node Type", "/versions/17/facts/2/label": "Inputs", "/versions/17/facts/2/value": "Multiple child plans", "/versions/17/facts/3/label": "Output", "/versions/17/facts/3/value": "Combined tuples", "/versions/17/facts/4/label": "Executor initializer", "/versions/17/facts/5/label": "Memory mechanism", "/versions/17/tables/0/title": "EXPLAIN labels in this source build", "/versions/17/related/1/label": "Using EXPLAIN", "/versions/17/related/2/label": "Parallel plans", "/versions/17/sections/0/title": "EXPLAIN names and attributes", "/versions/17/sections/1/title": "Memory and temporary storage", "/versions/17/sections/2/title": "Parallel execution and instrumentation", "/versions/17/sections/3/title": "Same-version manual discussion", "/versions/17/sections/4/title": "Examples from this manual build", "/versions/17/sections/5/title": "Executor implementation notes", "/versions/17/sections/6/title": "EXPLAIN identity in core source", "/versions/17/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.", "/versions/17/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/17/sections/0/paragraphs/1": "Text names recorded by this source: Append.", "/versions/17/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/17/sections/1/paragraphs/0": "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.", "/versions/17/sections/2/paragraphs/0": "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.", "/versions/17/sections/2/paragraphs/1": "Callbacks in this build: ExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM.", "/versions/17/sections/3/paragraphs/0": "Normally, EXPLAIN will display every plan node created by the planner. However, there are cases where the executor can determine that certain nodes need not be executed because they cannot produce any rows, based on parameter values that were not available at planning time. (Currently this can only happen for child nodes of an Append or MergeAppend node that is scanning a partitioned table.) When this happens, those plan nodes are omitted from the EXPLAIN output and a Subplans Removed: N annotation appears instead.", "/versions/17/sections/3/paragraphs/1": "Whenever PostgreSQL needs to combine rows from multiple sources into a single result set, it uses an Append or MergeAppend plan node. This commonly happens when implementing UNION ALL or when scanning a partitioned table. Such nodes can be used in parallel plans just as they can in any other plan. However, in a parallel plan, the planner may instead use a Parallel Append node.", "/versions/17/sections/3/paragraphs/2": "When an Append node is used in a parallel plan, each process will execute the child plans in the order in which they appear, so that all participating processes cooperate to execute the first child plan until it is complete and then move to the second plan at around the same time. When a Parallel Append is used instead, the executor will instead spread out the participating processes as evenly as possible across its child plans, so that multiple child plans are executed simultaneously. This avoids contention, and also avoids paying the startup cost of a child plan in those processes that never execute it.", "/versions/17/sections/3/paragraphs/3": "Also, unlike a regular Append node, which can only have partial children when used within a parallel plan, a Parallel Append node can have both partial and non-partial child plans. Non-partial children will be scanned by only a single process, since scanning them more than once would produce duplicate results. Plans that involve appending multiple results sets can therefore achieve coarse-grained parallelism even when efficient partial plans are not available. For example, consider a query against a partitioned table that can only be implemented efficiently by using an index that does not support parallel scans. The planner might choose a Parallel Append of regular Index Scan plans; each individual index scan would have to be executed to completion by a single process, but different scans could be performed at the same time by different processes.", "/versions/17/sections/5/paragraphs/0": "NOTES Each append node contains a list of one or more subplans which must be iteratively processed (forwards or backwards). Tuples are retrieved by executing the 'whichplan'th subplan until the subplan stops returning tuples, at which point that plan is shut down and the next started up.", "/versions/17/sections/5/paragraphs/1": "Append nodes don't make use of their left and right subtrees, rather they maintain a list of subplans so a typical append node looks like this in the plan tree:", "/versions/17/sections/5/paragraphs/3": "Append nodes are currently used for unions, and to support inheritance queries, where several relations need to be scanned. For example, in our standard person/student/employee/student-emp example, where student and employee inherit from person and student-emp inherits from student and employee, the query:", "/versions/17/tables/0/columns/0/label": "Text-format label", "/versions/17/tables/0/columns/1/label": "Structured node identity", "/versions/17/sections/4/blocks/0/paragraphs/0": "Example copied from the PostgreSQL 17.11 manual; it was not executed for this collection.", "/versions/17/sections/4/blocks/0/paragraphs/1": "When an UPDATE , DELETE , or MERGE command affects a partitioned table or inheritance hierarchy, the output might look like this:"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "a4f944a2908bed2d684ad16e56475ef725d54f3a44613e5cfa1512949dc95f6b"}, "evidence_kind": "source and documentation", "explain_names": ["Append"], "partial_modes": [], "comparison_data": {"node_tag": "T_Append", "strategies": [], "text_names": ["Append"], "initializer": "ExecInitAppend", "partial_modes": [], "memory_mechanism": "unclassified", "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "comparison_hash": "05fc087ef5a99b9d2d14f9b7e397d941085dafd8c263de24871ec9926b47ad8f", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeAppend.c"}, "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "18": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_Append"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "Append"}, {"label": "\u8f93\u5165", "value": "\u591a\u4e2a\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5408\u5e76\u540e\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitAppend"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "unclassified"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "bfe49b7e44ce4c31878392c3d84eb5c6fa97a5185a39aca44ff1914033a84ad3", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}], "mechanism": "unclassified", "description": "\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002", "source_notes": []}, "tables": [{"key": "explain-labels", "rows": [{"label": "Append", "identity": "Append"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=18", "label": "EXPLAIN"}, {"url": "/docs/18/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/18/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/enable_parallel_append/?v=18", "label": "enable_parallel_append"}, {"url": "/wiki/guc/enable_async_append/?v=18", "label": "enable_async_append"}], "release": {"ref": "PostgreSQL 18.6 source archive", "label": "18.6", "major": "18", "channel": "stable", "revision": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f", "source_url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "line": 1406, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1406", "sha256": "34c86d6070224a0e981efef51f79101d6d505e5874f1684ace183034bab14bb4", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "line": 181, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:181", "sha256": "f8a06a3f539077249b20664b2812433db6d7bd12b2c0ca633525db43d06f112a", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "bfe49b7e44ce4c31878392c3d84eb5c6fa97a5185a39aca44ff1914033a84ad3", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "52422b327a8049fbbb20d8b96008a0fc0a6fafa60f7eff3c695d5b2e83830120", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://pg.center/docs/18/using-explain.html#USING-EXPLAIN-CAVEATS", "path": "using-explain.html", "label": "PostgreSQL 18.6 \u00b7 using-explain", "sha256": "60040c30180093418a0affe56dd27dff9df2504b705b38039589e458bf5c31ed", "language": "en", "original_url": "/docs/18/using-explain.html#USING-EXPLAIN-CAVEATS"}, {"url": "https://pg.center/docs/18/parallel-plans.html#PARALLEL-APPEND", "path": "parallel-plans.html", "label": "PostgreSQL 18.6 \u00b7 parallel-plans", "sha256": "62207d207bead82b01b59dc119c4f95856f08655cc11d4699a05a40867ed2070", "language": "en", "original_url": "/docs/18/parallel-plans.html#PARALLEL-APPEND"}, {"url": "https://pg.center/docs/18/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 18.6 \u00b7 using-explain", "sha256": "60040c30180093418a0affe56dd27dff9df2504b705b38039589e458bf5c31ed", "language": "en", "original_url": "/docs/18/using-explain.html#USING-EXPLAIN-ANALYZE"}], "node_tag": "T_Append", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aAppend.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1aExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM."]}, {"title": "\u540c\u7248\u672c\u624b\u518c\u8bf4\u660e", "paragraphs": ["\u901a\u5e38 EXPLAIN \u663e\u793a\u89c4\u5212\u5668\u521b\u5efa\u7684\u6bcf\u4e2a\u8282\u70b9\u3002\u4f46\u6267\u884c\u5668\u6709\u65f6\u53ef\u4ee5\u6839\u636e\u89c4\u5212\u9636\u6bb5\u5c1a\u4e0d\u53ef\u77e5\u7684\u53c2\u6570\u503c\uff0c\u5224\u5b9a\u67d0\u4e9b\u8282\u70b9\u65e0\u6cd5\u4ea7\u751f\u4efb\u4f55\u884c\uff0c\u56e0\u6b64\u4e0d\u5fc5\u6267\u884c\u3002\uff08\u76ee\u524d\u4ec5\u4f1a\u53d1\u751f\u5728\u626b\u63cf\u5206\u533a\u8868\u7684 Append \u6216 MergeAppend \u8282\u70b9\u7684\u5b50\u8282\u70b9\u4e0a\u3002\uff09\u6b64\u65f6 EXPLAIN \u7701\u7565\u8fd9\u4e9b\u8282\u70b9\uff0c\u6539\u4e3a\u663e\u793a Subplans Removed: N\u3002", "\u6bcf\u5f53 PostgreSQL \u9700\u8981\u5c06\u6765\u81ea\u591a\u4e2a\u6e90\u7684\u884c\u5408\u5e76\u6210\u4e00\u4e2a\u7ed3\u679c\u96c6\u65f6\uff0c\u5b83\u5c31\u4f1a\u4f7f\u7528 Append \u6216 MergeAppend \u8ba1\u5212\u8282\u70b9\u3002\u8fd9\u79cd\u60c5\u51b5\u5e38\u89c1\u4e8e\u5b9e\u73b0 UNION ALL \u6216\u626b\u63cf\u5206\u533a\u8868\u65f6\u3002\u8fd9\u6837\u7684\u8282\u70b9\u548c\u5176\u4ed6\u4efb\u4f55\u8ba1\u5212\u4e2d\u7684\u60c5\u5f62\u4e00\u6837\uff0c\u4e5f\u53ef\u4ee5\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u3002\u4e0d\u8fc7\uff0c\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\uff0c\u89c4\u5212\u5668\u4e5f\u53ef\u80fd\u6539\u7528 Parallel Append \u8282\u70b9\u3002", "\u5f53 Append \u8282\u70b9\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u65f6\uff0c\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u4f1a\u6309\u7167\u5b50\u8ba1\u5212\u51fa\u73b0\u7684\u987a\u5e8f\u6267\u884c\u5b83\u4eec\uff0c\u56e0\u6b64\u6240\u6709\u53c2\u4e0e\u8fdb\u7a0b\u4f1a\u534f\u4f5c\u6267\u884c\u7b2c\u4e00\u4e2a\u5b50\u8ba1\u5212\u76f4\u5230\u5176\u5b8c\u6210\uff0c\u7136\u540e\u518d\u5927\u81f4\u540c\u65f6\u8f6c\u5411\u7b2c\u4e8c\u4e2a\u5b50\u8ba1\u5212\u3002\u800c\u5f53\u4f7f\u7528 Parallel Append \u65f6\uff0c\u6267\u884c\u5668\u4f1a\u5c3d\u53ef\u80fd\u5747\u5300\u5730\u5c06\u53c2\u4e0e\u8fdb\u7a0b\u5206\u6563\u5230\u5404\u4e2a\u5b50\u8ba1\u5212\u4e0a\uff0c\u4ece\u800c\u4f7f\u591a\u4e2a\u5b50\u8ba1\u5212\u80fd\u591f\u540c\u65f6\u6267\u884c\u3002\u8fd9\u6837\u65e2\u907f\u514d\u4e86\u4e89\u7528\uff0c\u4e5f\u907f\u514d\u8ba9\u90a3\u4e9b\u4ece\u672a\u6267\u884c\u67d0\u4e2a\u5b50\u8ba1\u5212\u7684\u8fdb\u7a0b\u627f\u62c5\u5176\u542f\u52a8\u4ee3\u4ef7\u3002", "\u6b64\u5916\uff0c\u4e0e\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\u53ea\u80fd\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\u7684\u666e\u901a Append \u8282\u70b9\u4e0d\u540c\uff0cParallel Append \u8282\u70b9\u65e2\u53ef\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\uff0c\u4e5f\u53ef\u5305\u542b\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u3002\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u53ea\u7531\u4e00\u4e2a\u8fdb\u7a0b\u626b\u63cf\uff0c\u56e0\u4e3a\u591a\u6b21\u626b\u63cf\u4f1a\u4ea7\u751f\u91cd\u590d\u7ed3\u679c\u3002\u56e0\u6b64\uff0c\u5373\u4f7f\u6ca1\u6709\u9ad8\u6548\u7684\u90e8\u5206\u8ba1\u5212\uff0c\u62fc\u63a5\u591a\u4e2a\u7ed3\u679c\u96c6\u7684\u8ba1\u5212\u4e5f\u80fd\u5b9e\u73b0\u7c97\u7c92\u5ea6\u5e76\u884c\u3002\u4f8b\u5982\uff0c\u9488\u5bf9\u5206\u533a\u8868\u7684\u67e5\u8be2\uff0c\u53ef\u80fd\u53ea\u6709\u501f\u52a9\u4e0d\u652f\u6301\u5e76\u884c\u626b\u63cf\u7684\u7d22\u5f15\u624d\u80fd\u9ad8\u6548\u6267\u884c\u3002\u89c4\u5212\u5668\u53ef\u80fd\u9009\u62e9\u4f7f\u7528 Parallel Append \u62fc\u63a5\u591a\u4e2a\u666e\u901a Index Scan \u8ba1\u5212\uff1b\u6bcf\u6b21\u7d22\u5f15\u626b\u63cf\u90fd\u5fc5\u987b\u7531\u5355\u4e2a\u8fdb\u7a0b\u5b8c\u6574\u6267\u884c\uff0c\u4f46\u4e0d\u540c\u626b\u63cf\u53ef\u4ee5\u7531\u4e0d\u540c\u8fdb\u7a0b\u540c\u65f6\u6267\u884c\u3002"]}, {"title": "\u672c\u7248\u624b\u518c\u4e2d\u7684\u793a\u4f8b", "blocks": [{"code": "EXPLAIN UPDATE gtest_parent SET f1 = CURRENT_DATE WHERE f2 = 101;\n\n                                       QUERY PLAN\n----------------------------------------------------------------------------------------\n Update on gtest_parent  (cost=0.00..3.06 rows=0 width=0)\n   Update on gtest_child gtest_parent_1\n   Update on gtest_child2 gtest_parent_2\n   Update on gtest_child3 gtest_parent_3\n   ->  Append  (cost=0.00..3.06 rows=3 width=14)\n         ->  Seq Scan on gtest_child gtest_parent_1  (cost=0.00..1.01 rows=1 width=14)\n               Filter: (f2 = 101)\n         ->  Seq Scan on gtest_child2 gtest_parent_2  (cost=0.00..1.01 rows=1 width=14)\n               Filter: (f2 = 101)\n         ->  Seq Scan on gtest_child3 gtest_parent_3  (cost=0.00..1.01 rows=1 width=14)\n               Filter: (f2 = 101)", "source": {"url": "/docs/18/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 18.6 \u00b7 using-explain", "sha256": "60040c30180093418a0affe56dd27dff9df2504b705b38039589e458bf5c31ed"}, "paragraphs": ["\u793a\u4f8b\u6458\u81ea PostgreSQL 18.6 \u624b\u518c\uff1b\u672c\u767e\u79d1\u672a\u5b9e\u9645\u6267\u884c\u6b64\u793a\u4f8b\u3002", "\u5f53 UPDATE \u3001 DELETE \u6216 MERGE \u547d\u4ee4\u5f71\u54cd\u5206\u533a\u8868\u6216\u7ee7\u627f\u5c42\u6b21\u65f6\uff0c\u8f93\u51fa\u53ef\u80fd\u50cf\u8fd9\u6837\uff1a"]}]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["\u8bf4\u660e\uff1a\u6bcf\u4e2a Append \u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5fc5\u987b\u9010\u4e00\u5904\u7406\u7684\u5b50\u8ba1\u5212\uff0c\u65b9\u5411\u53ef\u4ee5\u6b63\u5411\u6216\u53cd\u5411\u3002\u6267\u884c\u7b2c whichplan \u4e2a\u5b50\u8ba1\u5212\u53d6\u56de\u5143\u7ec4\uff0c\u76f4\u5230\u5b83\u4e0d\u518d\u8fd4\u56de\u5143\u7ec4\uff0c\u7136\u540e\u5173\u95ed\u8be5\u8ba1\u5212\u5e76\u542f\u52a8\u4e0b\u4e00\u4e2a\u3002", "Append \u8282\u70b9\u4e0d\u4f7f\u7528\u5de6\u3001\u53f3\u5b50\u6811\uff0c\u800c\u662f\u7ef4\u62a4\u4e00\u4e2a\u5b50\u8ba1\u5212\u5217\u8868\uff0c\u56e0\u6b64\u5178\u578b\u7684 Append \u8282\u70b9\u5728\u8ba1\u5212\u6811\u4e2d\u5982\u4e0b\u6240\u793a\uff1a", "... / Append -------+------+------+--- nil / \\ | | | nil nil ... ... ... subplans", "Append \u8282\u70b9\u76ee\u524d\u7528\u4e8e\u5e76\u96c6\u64cd\u4f5c\uff0c\u4e5f\u7528\u4e8e\u9700\u8981\u626b\u63cf\u591a\u4e2a\u5173\u7cfb\u7684\u7ee7\u627f\u67e5\u8be2\u3002\u4f8b\u5982\uff0c\u5728\u6807\u51c6\u7684 person/student/employee/student-emp \u793a\u4f8b\u4e2d\uff0cstudent \u548c employee \u7ee7\u627f\u81ea person\uff0c\u800c student-emp \u540c\u65f6\u7ee7\u627f\u81ea student \u548c employee\uff0c\u67e5\u8be2\u5982\u4e0b\uff1a", "| Append -------+-------+--------+--------+ / \\ | | | | nil nil Scan Scan Scan Scan | | | | person employee student student-emp"]}, {"code": "case T_Append:\n\t\t\tpname = sname = \"Append\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u904d\u5386\u5404\u5b50\u8ba1\u5212\u5e76\u5408\u5e76\u5176\u8f93\u51fa\u884c\u3002"], "localization": {"status": "complete", "sources": [{"url": "/docs/18/parallel-plans.html", "method": "same-major semantic node", "sha256": "7fa104623c0b4cd22acf0929e40518fbed8fe368af3e3b124cf693bd7ab69f0c", "language": "zh", "matched_nodes": ["#PARALLEL-PLANS/div[6]/p[1]", "#PARALLEL-PLANS/div[6]/p[2]"]}, {"url": "/docs/18/using-explain.html", "method": "same-major semantic node", "sha256": "b8835ec9adbc70ec150667a6b5443f8d298222dc0cc8c2bd1abb1c1d64895904", "language": "zh", "matched_nodes": ["#USING-EXPLAIN/div[8]/p[29]"]}], "language": "zh", "original_text": {"/versions/18/description/0": "Visits its child plans and combines their rows.", "/versions/18/facts/0/label": "Core node tag", "/versions/18/facts/1/label": "Structured EXPLAIN Node Type", "/versions/18/facts/2/label": "Inputs", "/versions/18/facts/2/value": "Multiple child plans", "/versions/18/facts/3/label": "Output", "/versions/18/facts/3/value": "Combined tuples", "/versions/18/facts/4/label": "Executor initializer", "/versions/18/facts/5/label": "Memory mechanism", "/versions/18/tables/0/title": "EXPLAIN labels in this source build", "/versions/18/related/1/label": "Using EXPLAIN", "/versions/18/related/2/label": "Parallel plans", "/versions/18/sections/0/title": "EXPLAIN names and attributes", "/versions/18/sections/1/title": "Memory and temporary storage", "/versions/18/sections/2/title": "Parallel execution and instrumentation", "/versions/18/sections/3/title": "Same-version manual discussion", "/versions/18/sections/4/title": "Examples from this manual build", "/versions/18/sections/5/title": "Executor implementation notes", "/versions/18/sections/6/title": "EXPLAIN identity in core source", "/versions/18/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.", "/versions/18/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/18/sections/0/paragraphs/1": "Text names recorded by this source: Append.", "/versions/18/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/18/sections/1/paragraphs/0": "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.", "/versions/18/sections/2/paragraphs/0": "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.", "/versions/18/sections/2/paragraphs/1": "Callbacks in this build: ExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM.", "/versions/18/sections/3/paragraphs/0": "Normally, EXPLAIN will display every plan node created by the planner. However, there are cases where the executor can determine that certain nodes need not be executed because they cannot produce any rows, based on parameter values that were not available at planning time. (Currently this can only happen for child nodes of an Append or MergeAppend node that is scanning a partitioned table.) When this happens, those plan nodes are omitted from the EXPLAIN output and a Subplans Removed: N annotation appears instead.", "/versions/18/sections/3/paragraphs/1": "Whenever PostgreSQL needs to combine rows from multiple sources into a single result set, it uses an Append or MergeAppend plan node. This commonly happens when implementing UNION ALL or when scanning a partitioned table. Such nodes can be used in parallel plans just as they can in any other plan. However, in a parallel plan, the planner may instead use a Parallel Append node.", "/versions/18/sections/3/paragraphs/2": "When an Append node is used in a parallel plan, each process will execute the child plans in the order in which they appear, so that all participating processes cooperate to execute the first child plan until it is complete and then move to the second plan at around the same time. When a Parallel Append is used instead, the executor will instead spread out the participating processes as evenly as possible across its child plans, so that multiple child plans are executed simultaneously. This avoids contention, and also avoids paying the startup cost of a child plan in those processes that never execute it.", "/versions/18/sections/3/paragraphs/3": "Also, unlike a regular Append node, which can only have partial children when used within a parallel plan, a Parallel Append node can have both partial and non-partial child plans. Non-partial children will be scanned by only a single process, since scanning them more than once would produce duplicate results. Plans that involve appending multiple result sets can therefore achieve coarse-grained parallelism even when efficient partial plans are not available. For example, consider a query against a partitioned table that can only be implemented efficiently by using an index that does not support parallel scans. The planner might choose a Parallel Append of regular Index Scan plans; each individual index scan would have to be executed to completion by a single process, but different scans could be performed at the same time by different processes.", "/versions/18/sections/5/paragraphs/0": "NOTES Each append node contains a list of one or more subplans which must be iteratively processed (forwards or backwards). Tuples are retrieved by executing the 'whichplan'th subplan until the subplan stops returning tuples, at which point that plan is shut down and the next started up.", "/versions/18/sections/5/paragraphs/1": "Append nodes don't make use of their left and right subtrees, rather they maintain a list of subplans so a typical append node looks like this in the plan tree:", "/versions/18/sections/5/paragraphs/3": "Append nodes are currently used for unions, and to support inheritance queries, where several relations need to be scanned. For example, in our standard person/student/employee/student-emp example, where student and employee inherit from person and student-emp inherits from student and employee, the query:", "/versions/18/tables/0/columns/0/label": "Text-format label", "/versions/18/tables/0/columns/1/label": "Structured node identity", "/versions/18/sections/4/blocks/0/paragraphs/0": "Example copied from the PostgreSQL 18.6 manual; it was not executed for this collection.", "/versions/18/sections/4/blocks/0/paragraphs/1": "When an UPDATE , DELETE , or MERGE command affects a partitioned table or inheritance hierarchy, the output might look like this:"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "98705531ccd5bf753c83a0014cdbc4177f98a28d39a55e2a9e84947e2eb77640"}, "evidence_kind": "source and documentation", "explain_names": ["Append"], "partial_modes": [], "comparison_data": {"node_tag": "T_Append", "strategies": [], "text_names": ["Append"], "initializer": "ExecInitAppend", "partial_modes": [], "memory_mechanism": "unclassified", "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "comparison_hash": "05fc087ef5a99b9d2d14f9b7e397d941085dafd8c263de24871ec9926b47ad8f", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeAppend.c"}, "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "19": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_Append"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "Append"}, {"label": "\u8f93\u5165", "value": "\u591a\u4e2a\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5408\u5e76\u540e\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitAppend"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "unclassified"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "a1f9a8e01aa84afbf5348556f977bbe25a0cb11068a3468ec95120d09ab02171", "archive_sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86"}], "mechanism": "unclassified", "description": "\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002", "source_notes": []}, "tables": [{"key": "explain-labels", "rows": [{"label": "Append", "identity": "Append"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=19", "label": "EXPLAIN"}, {"url": "/docs/19/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/19/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/enable_parallel_append/?v=19", "label": "enable_parallel_append"}, {"url": "/wiki/guc/enable_async_append/?v=19", "label": "enable_async_append"}], "release": {"ref": "PostgreSQL 19beta4 source archive", "label": "19beta4", "major": "19", "channel": "preview", "revision": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86", "source_url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "line": 1418, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1418", "sha256": "8b115b1c194a4b54ae630209a741e293b1df49a9052f10b2de9ca092a48998e3", "archive_sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86"}, {"url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "line": 181, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:181", "sha256": "5e39b2037bed672da55104229ecc32da5abde44c26bcad01479edcfa044d09ed", "archive_sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86"}, {"url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "a1f9a8e01aa84afbf5348556f977bbe25a0cb11068a3468ec95120d09ab02171", "archive_sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86"}, {"url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "1c65d5d6b6c81c71531685843647869bcae630779d815a5036b06e070c6c06c7", "archive_sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86"}, {"url": "https://pg.center/docs/19/using-explain.html#USING-EXPLAIN-CAVEATS", "path": "using-explain.html", "label": "PostgreSQL 19beta4 \u00b7 using-explain", "sha256": "52f111fbd213e2200146319d01a9dcc2ea90001617d2a28edc52f7954c2dd70b", "language": "en", "original_url": "/docs/19/using-explain.html#USING-EXPLAIN-CAVEATS"}, {"url": "https://pg.center/docs/19/parallel-plans.html#PARALLEL-APPEND", "path": "parallel-plans.html", "label": "PostgreSQL 19beta4 \u00b7 parallel-plans", "sha256": "f99fee3456a48a5ce2c399d6b35ab93183c2c9012e8ed60c53c0c253f79c3756", "language": "en", "original_url": "/docs/19/parallel-plans.html#PARALLEL-APPEND"}, {"url": "https://pg.center/docs/19/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 19beta4 \u00b7 using-explain", "sha256": "52f111fbd213e2200146319d01a9dcc2ea90001617d2a28edc52f7954c2dd70b", "language": "en", "original_url": "/docs/19/using-explain.html#USING-EXPLAIN-ANALYZE"}], "node_tag": "T_Append", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aAppend.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1aExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM."]}, {"title": "\u540c\u7248\u672c\u624b\u518c\u8bf4\u660e", "paragraphs": ["\u901a\u5e38 EXPLAIN \u663e\u793a\u89c4\u5212\u5668\u521b\u5efa\u7684\u6bcf\u4e2a\u8282\u70b9\u3002\u4f46\u6267\u884c\u5668\u6709\u65f6\u53ef\u4ee5\u6839\u636e\u89c4\u5212\u9636\u6bb5\u5c1a\u4e0d\u53ef\u77e5\u7684\u53c2\u6570\u503c\uff0c\u5224\u5b9a\u67d0\u4e9b\u8282\u70b9\u65e0\u6cd5\u4ea7\u751f\u4efb\u4f55\u884c\uff0c\u56e0\u6b64\u4e0d\u5fc5\u6267\u884c\u3002\uff08\u76ee\u524d\u4ec5\u4f1a\u53d1\u751f\u5728\u626b\u63cf\u5206\u533a\u8868\u7684 Append \u6216 MergeAppend \u8282\u70b9\u7684\u5b50\u8282\u70b9\u4e0a\u3002\uff09\u6b64\u65f6 EXPLAIN \u7701\u7565\u8fd9\u4e9b\u8282\u70b9\uff0c\u6539\u4e3a\u663e\u793a Subplans Removed: N\u3002", "\u6bcf\u5f53 PostgreSQL \u9700\u8981\u5c06\u6765\u81ea\u591a\u4e2a\u6e90\u7684\u884c\u5408\u5e76\u6210\u4e00\u4e2a\u7ed3\u679c\u96c6\u65f6\uff0c\u5b83\u5c31\u4f1a\u4f7f\u7528 Append \u6216 MergeAppend \u8ba1\u5212\u8282\u70b9\u3002\u8fd9\u79cd\u60c5\u51b5\u5e38\u89c1\u4e8e\u5b9e\u73b0 UNION ALL \u6216\u626b\u63cf\u5206\u533a\u8868\u65f6\u3002\u8fd9\u6837\u7684\u8282\u70b9\u548c\u5176\u4ed6\u4efb\u4f55\u8ba1\u5212\u4e2d\u7684\u60c5\u5f62\u4e00\u6837\uff0c\u4e5f\u53ef\u4ee5\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u3002\u4e0d\u8fc7\uff0c\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\uff0c\u89c4\u5212\u5668\u4e5f\u53ef\u80fd\u6539\u7528 Parallel Append \u8282\u70b9\u3002", "\u5f53 Append \u8282\u70b9\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u65f6\uff0c\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u4f1a\u6309\u7167\u5b50\u8ba1\u5212\u51fa\u73b0\u7684\u987a\u5e8f\u6267\u884c\u5b83\u4eec\uff0c\u56e0\u6b64\u6240\u6709\u53c2\u4e0e\u8fdb\u7a0b\u4f1a\u534f\u4f5c\u6267\u884c\u7b2c\u4e00\u4e2a\u5b50\u8ba1\u5212\u76f4\u5230\u5176\u5b8c\u6210\uff0c\u7136\u540e\u518d\u5927\u81f4\u540c\u65f6\u8f6c\u5411\u7b2c\u4e8c\u4e2a\u5b50\u8ba1\u5212\u3002\u800c\u5f53\u4f7f\u7528 Parallel Append \u65f6\uff0c\u6267\u884c\u5668\u4f1a\u5c3d\u53ef\u80fd\u5747\u5300\u5730\u5c06\u53c2\u4e0e\u8fdb\u7a0b\u5206\u6563\u5230\u5404\u4e2a\u5b50\u8ba1\u5212\u4e0a\uff0c\u4ece\u800c\u4f7f\u591a\u4e2a\u5b50\u8ba1\u5212\u80fd\u591f\u540c\u65f6\u6267\u884c\u3002\u8fd9\u6837\u65e2\u907f\u514d\u4e86\u4e89\u7528\uff0c\u4e5f\u907f\u514d\u8ba9\u90a3\u4e9b\u4ece\u672a\u6267\u884c\u67d0\u4e2a\u5b50\u8ba1\u5212\u7684\u8fdb\u7a0b\u627f\u62c5\u5176\u542f\u52a8\u4ee3\u4ef7\u3002", "\u6b64\u5916\uff0c\u4e0e\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\u53ea\u80fd\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\u7684\u666e\u901a Append \u8282\u70b9\u4e0d\u540c\uff0cParallel Append \u8282\u70b9\u65e2\u53ef\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\uff0c\u4e5f\u53ef\u5305\u542b\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u3002\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u53ea\u7531\u4e00\u4e2a\u8fdb\u7a0b\u626b\u63cf\uff0c\u56e0\u4e3a\u591a\u6b21\u626b\u63cf\u4f1a\u4ea7\u751f\u91cd\u590d\u7ed3\u679c\u3002\u56e0\u6b64\uff0c\u5373\u4f7f\u6ca1\u6709\u9ad8\u6548\u7684\u90e8\u5206\u8ba1\u5212\uff0c\u62fc\u63a5\u591a\u4e2a\u7ed3\u679c\u96c6\u7684\u8ba1\u5212\u4e5f\u80fd\u5b9e\u73b0\u7c97\u7c92\u5ea6\u5e76\u884c\u3002\u4f8b\u5982\uff0c\u9488\u5bf9\u5206\u533a\u8868\u7684\u67e5\u8be2\uff0c\u53ef\u80fd\u53ea\u6709\u501f\u52a9\u4e0d\u652f\u6301\u5e76\u884c\u626b\u63cf\u7684\u7d22\u5f15\u624d\u80fd\u9ad8\u6548\u6267\u884c\u3002\u89c4\u5212\u5668\u53ef\u80fd\u9009\u62e9\u4f7f\u7528 Parallel Append \u62fc\u63a5\u591a\u4e2a\u666e\u901a Index Scan \u8ba1\u5212\uff1b\u6bcf\u6b21\u7d22\u5f15\u626b\u63cf\u90fd\u5fc5\u987b\u7531\u5355\u4e2a\u8fdb\u7a0b\u5b8c\u6574\u6267\u884c\uff0c\u4f46\u4e0d\u540c\u626b\u63cf\u53ef\u4ee5\u7531\u4e0d\u540c\u8fdb\u7a0b\u540c\u65f6\u6267\u884c\u3002"]}, {"title": "\u672c\u7248\u624b\u518c\u4e2d\u7684\u793a\u4f8b", "blocks": [{"code": "EXPLAIN UPDATE gtest_parent SET f1 = CURRENT_DATE WHERE f2 = 101;\n\n                                       QUERY PLAN\n----------------------------------------------------------------------------------------\n Update on gtest_parent  (cost=0.00..3.06 rows=0 width=0)\n   Update on gtest_child gtest_parent_1\n   Update on gtest_child2 gtest_parent_2\n   Update on gtest_child3 gtest_parent_3\n   ->  Append  (cost=0.00..3.06 rows=3 width=14)\n         ->  Seq Scan on gtest_child gtest_parent_1  (cost=0.00..1.01 rows=1 width=14)\n               Filter: (f2 = 101)\n         ->  Seq Scan on gtest_child2 gtest_parent_2  (cost=0.00..1.01 rows=1 width=14)\n               Filter: (f2 = 101)\n         ->  Seq Scan on gtest_child3 gtest_parent_3  (cost=0.00..1.01 rows=1 width=14)\n               Filter: (f2 = 101)", "source": {"url": "/docs/19/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 19beta4 \u00b7 using-explain", "sha256": "52f111fbd213e2200146319d01a9dcc2ea90001617d2a28edc52f7954c2dd70b"}, "paragraphs": ["\u793a\u4f8b\u6458\u81ea PostgreSQL 19beta4 \u624b\u518c\uff1b\u672c\u767e\u79d1\u672a\u5b9e\u9645\u6267\u884c\u6b64\u793a\u4f8b\u3002", "\u5f53 UPDATE \u3001 DELETE \u6216 MERGE \u547d\u4ee4\u5f71\u54cd\u5206\u533a\u8868\u6216\u7ee7\u627f\u5c42\u6b21\u65f6\uff0c\u8f93\u51fa\u53ef\u80fd\u50cf\u8fd9\u6837\uff1a"]}]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["\u8bf4\u660e\uff1a\u6bcf\u4e2a Append \u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5fc5\u987b\u9010\u4e00\u5904\u7406\u7684\u5b50\u8ba1\u5212\uff0c\u65b9\u5411\u53ef\u4ee5\u6b63\u5411\u6216\u53cd\u5411\u3002\u6267\u884c\u7b2c whichplan \u4e2a\u5b50\u8ba1\u5212\u53d6\u56de\u5143\u7ec4\uff0c\u76f4\u5230\u5b83\u4e0d\u518d\u8fd4\u56de\u5143\u7ec4\uff0c\u7136\u540e\u5173\u95ed\u8be5\u8ba1\u5212\u5e76\u542f\u52a8\u4e0b\u4e00\u4e2a\u3002", "Append \u8282\u70b9\u4e0d\u4f7f\u7528\u5de6\u3001\u53f3\u5b50\u6811\uff0c\u800c\u662f\u7ef4\u62a4\u4e00\u4e2a\u5b50\u8ba1\u5212\u5217\u8868\uff0c\u56e0\u6b64\u5178\u578b\u7684 Append \u8282\u70b9\u5728\u8ba1\u5212\u6811\u4e2d\u5982\u4e0b\u6240\u793a\uff1a", "... / Append -------+------+------+--- nil / \\ | | | nil nil ... ... ... subplans", "Append \u8282\u70b9\u76ee\u524d\u7528\u4e8e\u5e76\u96c6\u64cd\u4f5c\uff0c\u4e5f\u7528\u4e8e\u9700\u8981\u626b\u63cf\u591a\u4e2a\u5173\u7cfb\u7684\u7ee7\u627f\u67e5\u8be2\u3002\u4f8b\u5982\uff0c\u5728\u6807\u51c6\u7684 person/student/employee/student-emp \u793a\u4f8b\u4e2d\uff0cstudent \u548c employee \u7ee7\u627f\u81ea person\uff0c\u800c student-emp \u540c\u65f6\u7ee7\u627f\u81ea student \u548c employee\uff0c\u67e5\u8be2\u5982\u4e0b\uff1a", "| Append -------+-------+--------+--------+ / \\ | | | | nil nil Scan Scan Scan Scan | | | | person employee student student-emp"]}, {"code": "case T_Append:\n\t\t\tpname = sname = \"Append\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u904d\u5386\u5404\u5b50\u8ba1\u5212\u5e76\u5408\u5e76\u5176\u8f93\u51fa\u884c\u3002"], "localization": {"status": "complete", "sources": [{"url": "/docs/19/parallel-plans.html", "method": "same-major semantic node", "sha256": "c162417a8d7d4bf4b4b79ba445207cd01020c24ca11178e13a9fa3d7d8ca8e2e", "language": "zh", "matched_nodes": ["#PARALLEL-PLANS/div[6]/p[1]", "#PARALLEL-PLANS/div[6]/p[2]"]}, {"url": "/docs/19/using-explain.html", "method": "same-major semantic node", "sha256": "7cc78f59bf29afb1811ece53e9d5c572a3f634d66d7422fb8761f19bc6811492", "language": "zh", "matched_nodes": ["#USING-EXPLAIN/div[8]/p[32]"]}], "language": "zh", "original_text": {"/versions/19/description/0": "Visits its child plans and combines their rows.", "/versions/19/facts/0/label": "Core node tag", "/versions/19/facts/1/label": "Structured EXPLAIN Node Type", "/versions/19/facts/2/label": "Inputs", "/versions/19/facts/2/value": "Multiple child plans", "/versions/19/facts/3/label": "Output", "/versions/19/facts/3/value": "Combined tuples", "/versions/19/facts/4/label": "Executor initializer", "/versions/19/facts/5/label": "Memory mechanism", "/versions/19/tables/0/title": "EXPLAIN labels in this source build", "/versions/19/related/1/label": "Using EXPLAIN", "/versions/19/related/2/label": "Parallel plans", "/versions/19/sections/0/title": "EXPLAIN names and attributes", "/versions/19/sections/1/title": "Memory and temporary storage", "/versions/19/sections/2/title": "Parallel execution and instrumentation", "/versions/19/sections/3/title": "Same-version manual discussion", "/versions/19/sections/4/title": "Examples from this manual build", "/versions/19/sections/5/title": "Executor implementation notes", "/versions/19/sections/6/title": "EXPLAIN identity in core source", "/versions/19/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.", "/versions/19/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/19/sections/0/paragraphs/1": "Text names recorded by this source: Append.", "/versions/19/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/19/sections/1/paragraphs/0": "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.", "/versions/19/sections/2/paragraphs/0": "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.", "/versions/19/sections/2/paragraphs/1": "Callbacks in this build: ExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM.", "/versions/19/sections/3/paragraphs/0": "Normally, EXPLAIN will display every plan node created by the planner. However, there are cases where the executor can determine that certain nodes need not be executed because they cannot produce any rows, based on parameter values that were not available at planning time. (Currently this can only happen for child nodes of an Append or MergeAppend node that is scanning a partitioned table.) When this happens, those plan nodes are omitted from the EXPLAIN output and a Subplans Removed: N annotation appears instead.", "/versions/19/sections/3/paragraphs/1": "Whenever PostgreSQL needs to combine rows from multiple sources into a single result set, it uses an Append or MergeAppend plan node. This commonly happens when implementing UNION ALL or when scanning a partitioned table. Such nodes can be used in parallel plans just as they can in any other plan. However, in a parallel plan, the planner may instead use a Parallel Append node.", "/versions/19/sections/3/paragraphs/2": "When an Append node is used in a parallel plan, each process will execute the child plans in the order in which they appear, so that all participating processes cooperate to execute the first child plan until it is complete and then move to the second plan at around the same time. When a Parallel Append is used instead, the executor will instead spread out the participating processes as evenly as possible across its child plans, so that multiple child plans are executed simultaneously. This avoids contention, and also avoids paying the startup cost of a child plan in those processes that never execute it.", "/versions/19/sections/3/paragraphs/3": "Also, unlike a regular Append node, which can only have partial children when used within a parallel plan, a Parallel Append node can have both partial and non-partial child plans. Non-partial children will be scanned by only a single process, since scanning them more than once would produce duplicate results. Plans that involve appending multiple result sets can therefore achieve coarse-grained parallelism even when efficient partial plans are not available. For example, consider a query against a partitioned table that can only be implemented efficiently by using an index that does not support parallel scans. The planner might choose a Parallel Append of regular Index Scan plans; each individual index scan would have to be executed to completion by a single process, but different scans could be performed at the same time by different processes.", "/versions/19/sections/5/paragraphs/0": "NOTES Each append node contains a list of one or more subplans which must be iteratively processed (forwards or backwards). Tuples are retrieved by executing the 'whichplan'th subplan until the subplan stops returning tuples, at which point that plan is shut down and the next started up.", "/versions/19/sections/5/paragraphs/1": "Append nodes don't make use of their left and right subtrees, rather they maintain a list of subplans so a typical append node looks like this in the plan tree:", "/versions/19/sections/5/paragraphs/3": "Append nodes are currently used for unions, and to support inheritance queries, where several relations need to be scanned. For example, in our standard person/student/employee/student-emp example, where student and employee inherit from person and student-emp inherits from student and employee, the query:", "/versions/19/tables/0/columns/0/label": "Text-format label", "/versions/19/tables/0/columns/1/label": "Structured node identity", "/versions/19/sections/4/blocks/0/paragraphs/0": "Example copied from the PostgreSQL 19beta4 manual; it was not executed for this collection.", "/versions/19/sections/4/blocks/0/paragraphs/1": "When an UPDATE , DELETE , or MERGE command affects a partitioned table or inheritance hierarchy, the output might look like this:"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "dc909ed9835f259a075aca4ca4b75c2e11fc20d322e11d8b3e490652de1c3914"}, "evidence_kind": "source and documentation", "explain_names": ["Append"], "partial_modes": [], "comparison_data": {"node_tag": "T_Append", "strategies": [], "text_names": ["Append"], "initializer": "ExecInitAppend", "partial_modes": [], "memory_mechanism": "unclassified", "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "comparison_hash": "05fc087ef5a99b9d2d14f9b7e397d941085dafd8c263de24871ec9926b47ad8f", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeAppend.c"}, "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "20": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_Append"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "Append"}, {"label": "\u8f93\u5165", "value": "\u591a\u4e2a\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5408\u5e76\u540e\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitAppend"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "unclassified"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "c0723b4692f6c7b4a79bdeb8780c1fa510b5fdd9c72024507c4a8e216bf90cb9", "archive_sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41"}], "mechanism": "unclassified", "description": "\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002", "source_notes": []}, "tables": [{"key": "explain-labels", "rows": [{"label": "Append", "identity": "Append"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=20", "label": "EXPLAIN"}, {"url": "/docs/devel/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/devel/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/enable_parallel_append/?v=20", "label": "enable_parallel_append"}, {"url": "/wiki/guc/enable_async_append/?v=20", "label": "enable_async_append"}], "release": {"ref": "PostgreSQL 20devel source archive", "label": "20devel", "major": "20", "channel": "devel", "revision": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41", "source_url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "source_snapshot_utc": "26-Sep-2026 20:22"}, "sources": [{"url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "line": 1418, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1418", "sha256": "13402758013520451539427b5993db06d463ca11c4e2d4cc5444e82367688077", "archive_sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41"}, {"url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "line": 181, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:181", "sha256": "5e39b2037bed672da55104229ecc32da5abde44c26bcad01479edcfa044d09ed", "archive_sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41"}, {"url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "c0723b4692f6c7b4a79bdeb8780c1fa510b5fdd9c72024507c4a8e216bf90cb9", "archive_sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41"}, {"url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "7a94ed1652f0d74d50c39971d1cd3e8051dbc0d6058f31b6de71a433ca343521", "archive_sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41"}, {"url": "https://pg.center/docs/devel/using-explain.html#USING-EXPLAIN-CAVEATS", "path": "using-explain.html", "label": "PostgreSQL 20devel \u00b7 using-explain", "sha256": "99cfea3035876ea63f88b75ba8c964b51a32a70606544e09f769c0b60a234b31", "language": "en", "original_url": "/docs/devel/using-explain.html#USING-EXPLAIN-CAVEATS"}, {"url": "https://pg.center/docs/devel/parallel-plans.html#PARALLEL-APPEND", "path": "parallel-plans.html", "label": "PostgreSQL 20devel \u00b7 parallel-plans", "sha256": "6451d4254d26d789b8697ba7207288ac26e75e56f9711c8a5a3f5480171a4724", "language": "en", "original_url": "/docs/devel/parallel-plans.html#PARALLEL-APPEND"}, {"url": "https://pg.center/docs/devel/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 20devel \u00b7 using-explain", "sha256": "99cfea3035876ea63f88b75ba8c964b51a32a70606544e09f769c0b60a234b31", "language": "en", "original_url": "/docs/devel/using-explain.html#USING-EXPLAIN-ANALYZE"}], "node_tag": "T_Append", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aAppend.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1aExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM."]}, {"title": "\u540c\u7248\u672c\u624b\u518c\u8bf4\u660e", "paragraphs": ["\u901a\u5e38 EXPLAIN \u663e\u793a\u89c4\u5212\u5668\u521b\u5efa\u7684\u6bcf\u4e2a\u8282\u70b9\u3002\u4f46\u6267\u884c\u5668\u6709\u65f6\u53ef\u4ee5\u6839\u636e\u89c4\u5212\u9636\u6bb5\u5c1a\u4e0d\u53ef\u77e5\u7684\u53c2\u6570\u503c\uff0c\u5224\u5b9a\u67d0\u4e9b\u8282\u70b9\u65e0\u6cd5\u4ea7\u751f\u4efb\u4f55\u884c\uff0c\u56e0\u6b64\u4e0d\u5fc5\u6267\u884c\u3002\uff08\u76ee\u524d\u4ec5\u4f1a\u53d1\u751f\u5728\u626b\u63cf\u5206\u533a\u8868\u7684 Append \u6216 MergeAppend \u8282\u70b9\u7684\u5b50\u8282\u70b9\u4e0a\u3002\uff09\u6b64\u65f6 EXPLAIN \u7701\u7565\u8fd9\u4e9b\u8282\u70b9\uff0c\u6539\u4e3a\u663e\u793a Subplans Removed: N\u3002", "\u6bcf\u5f53 PostgreSQL \u9700\u8981\u5c06\u6765\u81ea\u591a\u4e2a\u6e90\u7684\u884c\u5408\u5e76\u6210\u4e00\u4e2a\u7ed3\u679c\u96c6\u65f6\uff0c\u5b83\u5c31\u4f1a\u4f7f\u7528 Append \u6216 MergeAppend \u8ba1\u5212\u8282\u70b9\u3002\u8fd9\u79cd\u60c5\u51b5\u5e38\u89c1\u4e8e\u5b9e\u73b0 UNION ALL \u6216\u626b\u63cf\u5206\u533a\u8868\u65f6\u3002\u8fd9\u6837\u7684\u8282\u70b9\u548c\u5176\u4ed6\u4efb\u4f55\u8ba1\u5212\u4e2d\u7684\u60c5\u5f62\u4e00\u6837\uff0c\u4e5f\u53ef\u4ee5\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u3002\u4e0d\u8fc7\uff0c\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\uff0c\u89c4\u5212\u5668\u4e5f\u53ef\u80fd\u6539\u7528 Parallel Append \u8282\u70b9\u3002", "\u5f53 Append \u8282\u70b9\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u65f6\uff0c\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u4f1a\u6309\u7167\u5b50\u8ba1\u5212\u51fa\u73b0\u7684\u987a\u5e8f\u6267\u884c\u5b83\u4eec\uff0c\u56e0\u6b64\u6240\u6709\u53c2\u4e0e\u8fdb\u7a0b\u4f1a\u534f\u4f5c\u6267\u884c\u7b2c\u4e00\u4e2a\u5b50\u8ba1\u5212\u76f4\u5230\u5176\u5b8c\u6210\uff0c\u7136\u540e\u518d\u5927\u81f4\u540c\u65f6\u8f6c\u5411\u7b2c\u4e8c\u4e2a\u5b50\u8ba1\u5212\u3002\u800c\u5f53\u4f7f\u7528 Parallel Append \u65f6\uff0c\u6267\u884c\u5668\u4f1a\u5c3d\u53ef\u80fd\u5747\u5300\u5730\u5c06\u53c2\u4e0e\u8fdb\u7a0b\u5206\u6563\u5230\u5404\u4e2a\u5b50\u8ba1\u5212\u4e0a\uff0c\u4ece\u800c\u4f7f\u591a\u4e2a\u5b50\u8ba1\u5212\u80fd\u591f\u540c\u65f6\u6267\u884c\u3002\u8fd9\u6837\u65e2\u907f\u514d\u4e86\u4e89\u7528\uff0c\u4e5f\u907f\u514d\u8ba9\u90a3\u4e9b\u4ece\u672a\u6267\u884c\u67d0\u4e2a\u5b50\u8ba1\u5212\u7684\u8fdb\u7a0b\u627f\u62c5\u5176\u542f\u52a8\u4ee3\u4ef7\u3002", "\u6b64\u5916\uff0c\u4e0e\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\u53ea\u80fd\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\u7684\u666e\u901a Append \u8282\u70b9\u4e0d\u540c\uff0cParallel Append \u8282\u70b9\u65e2\u53ef\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\uff0c\u4e5f\u53ef\u5305\u542b\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u3002\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u53ea\u7531\u4e00\u4e2a\u8fdb\u7a0b\u626b\u63cf\uff0c\u56e0\u4e3a\u591a\u6b21\u626b\u63cf\u4f1a\u4ea7\u751f\u91cd\u590d\u7ed3\u679c\u3002\u56e0\u6b64\uff0c\u5373\u4f7f\u6ca1\u6709\u9ad8\u6548\u7684\u90e8\u5206\u8ba1\u5212\uff0c\u62fc\u63a5\u591a\u4e2a\u7ed3\u679c\u96c6\u7684\u8ba1\u5212\u4e5f\u80fd\u5b9e\u73b0\u7c97\u7c92\u5ea6\u5e76\u884c\u3002\u4f8b\u5982\uff0c\u9488\u5bf9\u5206\u533a\u8868\u7684\u67e5\u8be2\uff0c\u53ef\u80fd\u53ea\u6709\u501f\u52a9\u4e0d\u652f\u6301\u5e76\u884c\u626b\u63cf\u7684\u7d22\u5f15\u624d\u80fd\u9ad8\u6548\u6267\u884c\u3002\u89c4\u5212\u5668\u53ef\u80fd\u9009\u62e9\u4f7f\u7528 Parallel Append \u62fc\u63a5\u591a\u4e2a\u666e\u901a Index Scan \u8ba1\u5212\uff1b\u6bcf\u6b21\u7d22\u5f15\u626b\u63cf\u90fd\u5fc5\u987b\u7531\u5355\u4e2a\u8fdb\u7a0b\u5b8c\u6574\u6267\u884c\uff0c\u4f46\u4e0d\u540c\u626b\u63cf\u53ef\u4ee5\u7531\u4e0d\u540c\u8fdb\u7a0b\u540c\u65f6\u6267\u884c\u3002"]}, {"title": "\u672c\u7248\u624b\u518c\u4e2d\u7684\u793a\u4f8b", "blocks": [{"code": "EXPLAIN UPDATE gtest_parent SET f1 = CURRENT_DATE WHERE f2 = 101;\n\n                                       QUERY PLAN\n----------------------------------------------------------------------------------------\n Update on gtest_parent  (cost=0.00..3.06 rows=0 width=0)\n   Update on gtest_child gtest_parent_1\n   Update on gtest_child2 gtest_parent_2\n   Update on gtest_child3 gtest_parent_3\n   ->  Append  (cost=0.00..3.06 rows=3 width=14)\n         ->  Seq Scan on gtest_child gtest_parent_1  (cost=0.00..1.01 rows=1 width=14)\n               Filter: (f2 = 101)\n         ->  Seq Scan on gtest_child2 gtest_parent_2  (cost=0.00..1.01 rows=1 width=14)\n               Filter: (f2 = 101)\n         ->  Seq Scan on gtest_child3 gtest_parent_3  (cost=0.00..1.01 rows=1 width=14)\n               Filter: (f2 = 101)", "source": {"url": "/docs/devel/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 20devel \u00b7 using-explain", "sha256": "99cfea3035876ea63f88b75ba8c964b51a32a70606544e09f769c0b60a234b31"}, "paragraphs": ["\u793a\u4f8b\u6458\u81ea PostgreSQL 20devel \u624b\u518c\uff1b\u672c\u767e\u79d1\u672a\u5b9e\u9645\u6267\u884c\u6b64\u793a\u4f8b\u3002", "\u5f53 UPDATE \u3001 DELETE \u6216 MERGE \u547d\u4ee4\u5f71\u54cd\u5206\u533a\u8868\u6216\u7ee7\u627f\u5c42\u6b21\u65f6\uff0c\u8f93\u51fa\u53ef\u80fd\u50cf\u8fd9\u6837\uff1a"]}]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["\u8bf4\u660e\uff1a\u6bcf\u4e2a Append \u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5fc5\u987b\u9010\u4e00\u5904\u7406\u7684\u5b50\u8ba1\u5212\uff0c\u65b9\u5411\u53ef\u4ee5\u6b63\u5411\u6216\u53cd\u5411\u3002\u6267\u884c\u7b2c whichplan \u4e2a\u5b50\u8ba1\u5212\u53d6\u56de\u5143\u7ec4\uff0c\u76f4\u5230\u5b83\u4e0d\u518d\u8fd4\u56de\u5143\u7ec4\uff0c\u7136\u540e\u5173\u95ed\u8be5\u8ba1\u5212\u5e76\u542f\u52a8\u4e0b\u4e00\u4e2a\u3002", "Append \u8282\u70b9\u4e0d\u4f7f\u7528\u5de6\u3001\u53f3\u5b50\u6811\uff0c\u800c\u662f\u7ef4\u62a4\u4e00\u4e2a\u5b50\u8ba1\u5212\u5217\u8868\uff0c\u56e0\u6b64\u5178\u578b\u7684 Append \u8282\u70b9\u5728\u8ba1\u5212\u6811\u4e2d\u5982\u4e0b\u6240\u793a\uff1a", "... / Append -------+------+------+--- nil / \\ | | | nil nil ... ... ... subplans", "Append \u8282\u70b9\u76ee\u524d\u7528\u4e8e\u5e76\u96c6\u64cd\u4f5c\uff0c\u4e5f\u7528\u4e8e\u9700\u8981\u626b\u63cf\u591a\u4e2a\u5173\u7cfb\u7684\u7ee7\u627f\u67e5\u8be2\u3002\u4f8b\u5982\uff0c\u5728\u6807\u51c6\u7684 person/student/employee/student-emp \u793a\u4f8b\u4e2d\uff0cstudent \u548c employee \u7ee7\u627f\u81ea person\uff0c\u800c student-emp \u540c\u65f6\u7ee7\u627f\u81ea student \u548c employee\uff0c\u67e5\u8be2\u5982\u4e0b\uff1a", "| Append -------+-------+--------+--------+ / \\ | | | | nil nil Scan Scan Scan Scan | | | | person employee student student-emp"]}, {"code": "case T_Append:\n\t\t\tpname = sname = \"Append\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u904d\u5386\u5404\u5b50\u8ba1\u5212\u5e76\u5408\u5e76\u5176\u8f93\u51fa\u884c\u3002"], "localization": {"status": "complete", "sources": [{"url": "/docs/devel/parallel-plans.html", "method": "same-major semantic node", "sha256": "322333100879d0971d33685d4924d0c6b79bc429a74a35f9cca60c247e02b545", "language": "zh", "matched_nodes": ["#PARALLEL-PLANS/div[6]/p[1]", "#PARALLEL-PLANS/div[6]/p[2]"]}, {"url": "/docs/devel/using-explain.html", "method": "same-major semantic node", "sha256": "2744ee0e88d132c504bf5e102765edaabd393eb12c59294093db6d90b26dd65c", "language": "zh", "matched_nodes": ["#USING-EXPLAIN/div[8]/p[32]"]}], "language": "zh", "original_text": {"/summary": "Visits its child plans and combines their rows.", "/category": "Combination", "/versions/20/description/0": "Visits its child plans and combines their rows.", "/versions/20/facts/0/label": "Core node tag", "/versions/20/facts/1/label": "Structured EXPLAIN Node Type", "/versions/20/facts/2/label": "Inputs", "/versions/20/facts/2/value": "Multiple child plans", "/versions/20/facts/3/label": "Output", "/versions/20/facts/3/value": "Combined tuples", "/versions/20/facts/4/label": "Executor initializer", "/versions/20/facts/5/label": "Memory mechanism", "/versions/20/tables/0/title": "EXPLAIN labels in this source build", "/versions/20/related/1/label": "Using EXPLAIN", "/versions/20/related/2/label": "Parallel plans", "/versions/20/sections/0/title": "EXPLAIN names and attributes", "/versions/20/sections/1/title": "Memory and temporary storage", "/versions/20/sections/2/title": "Parallel execution and instrumentation", "/versions/20/sections/3/title": "Same-version manual discussion", "/versions/20/sections/4/title": "Examples from this manual build", "/versions/20/sections/5/title": "Executor implementation notes", "/versions/20/sections/6/title": "EXPLAIN identity in core source", "/versions/20/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.", "/versions/20/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/20/sections/0/paragraphs/1": "Text names recorded by this source: Append.", "/versions/20/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/20/sections/1/paragraphs/0": "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.", "/versions/20/sections/2/paragraphs/0": "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.", "/versions/20/sections/2/paragraphs/1": "Callbacks in this build: ExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM.", "/versions/20/sections/3/paragraphs/0": "Normally, EXPLAIN will display every plan node created by the planner. However, there are cases where the executor can determine that certain nodes need not be executed because they cannot produce any rows, based on parameter values that were not available at planning time. (Currently this can only happen for child nodes of an Append or MergeAppend node that is scanning a partitioned table.) When this happens, those plan nodes are omitted from the EXPLAIN output and a Subplans Removed: N annotation appears instead.", "/versions/20/sections/3/paragraphs/1": "Whenever PostgreSQL needs to combine rows from multiple sources into a single result set, it uses an Append or MergeAppend plan node. This commonly happens when implementing UNION ALL or when scanning a partitioned table. Such nodes can be used in parallel plans just as they can in any other plan. However, in a parallel plan, the planner may instead use a Parallel Append node.", "/versions/20/sections/3/paragraphs/2": "When an Append node is used in a parallel plan, each process will execute the child plans in the order in which they appear, so that all participating processes cooperate to execute the first child plan until it is complete and then move to the second plan at around the same time. When a Parallel Append is used instead, the executor will instead spread out the participating processes as evenly as possible across its child plans, so that multiple child plans are executed simultaneously. This avoids contention, and also avoids paying the startup cost of a child plan in those processes that never execute it.", "/versions/20/sections/3/paragraphs/3": "Also, unlike a regular Append node, which can only have partial children when used within a parallel plan, a Parallel Append node can have both partial and non-partial child plans. Non-partial children will be scanned by only a single process, since scanning them more than once would produce duplicate results. Plans that involve appending multiple result sets can therefore achieve coarse-grained parallelism even when efficient partial plans are not available. For example, consider a query against a partitioned table that can only be implemented efficiently by using an index that does not support parallel scans. The planner might choose a Parallel Append of regular Index Scan plans; each individual index scan would have to be executed to completion by a single process, but different scans could be performed at the same time by different processes.", "/versions/20/sections/5/paragraphs/0": "NOTES Each append node contains a list of one or more subplans which must be iteratively processed (forwards or backwards). Tuples are retrieved by executing the 'whichplan'th subplan until the subplan stops returning tuples, at which point that plan is shut down and the next started up.", "/versions/20/sections/5/paragraphs/1": "Append nodes don't make use of their left and right subtrees, rather they maintain a list of subplans so a typical append node looks like this in the plan tree:", "/versions/20/sections/5/paragraphs/3": "Append nodes are currently used for unions, and to support inheritance queries, where several relations need to be scanned. For example, in our standard person/student/employee/student-emp example, where student and employee inherit from person and student-emp inherits from student and employee, the query:", "/versions/20/tables/0/columns/0/label": "Text-format label", "/versions/20/tables/0/columns/1/label": "Structured node identity", "/versions/20/sections/4/blocks/0/paragraphs/0": "Example copied from the PostgreSQL 20devel manual; it was not executed for this collection.", "/versions/20/sections/4/blocks/0/paragraphs/1": "When an UPDATE , DELETE , or MERGE command affects a partitioned table or inheritance hierarchy, the output might look like this:"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "d9dca634bf7dee6218e1e10e97bdc251ed199a0a33d4ed97f5583452e7e1b3ad"}, "evidence_kind": "source and documentation", "explain_names": ["Append"], "partial_modes": [], "comparison_data": {"node_tag": "T_Append", "strategies": [], "text_names": ["Append"], "initializer": "ExecInitAppend", "partial_modes": [], "memory_mechanism": "unclassified", "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "comparison_hash": "05fc087ef5a99b9d2d14f9b7e397d941085dafd8c263de24871ec9926b47ad8f", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeAppend.c"}, "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}}}, "snapshot": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_Append"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "Append"}, {"label": "\u8f93\u5165", "value": "\u591a\u4e2a\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5408\u5e76\u540e\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitAppend"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "unclassified"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "bfe49b7e44ce4c31878392c3d84eb5c6fa97a5185a39aca44ff1914033a84ad3", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}], "mechanism": "unclassified", "description": "\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002", "source_notes": []}, "tables": [{"key": "explain-labels", "rows": [{"label": "Append", "identity": "Append"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=18", "label": "EXPLAIN"}, {"url": "/docs/18/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/18/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/enable_parallel_append/?v=18", "label": "enable_parallel_append"}, {"url": "/wiki/guc/enable_async_append/?v=18", "label": "enable_async_append"}], "release": {"ref": "PostgreSQL 18.6 source archive", "label": "18.6", "major": "18", "channel": "stable", "revision": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f", "source_url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "line": 1406, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1406", "sha256": "34c86d6070224a0e981efef51f79101d6d505e5874f1684ace183034bab14bb4", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "line": 181, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:181", "sha256": "f8a06a3f539077249b20664b2812433db6d7bd12b2c0ca633525db43d06f112a", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/backend/executor/nodeAppend.c", "label": "src/backend/executor/nodeAppend.c", "sha256": "bfe49b7e44ce4c31878392c3d84eb5c6fa97a5185a39aca44ff1914033a84ad3", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "52422b327a8049fbbb20d8b96008a0fc0a6fafa60f7eff3c695d5b2e83830120", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://pg.center/docs/18/using-explain.html#USING-EXPLAIN-CAVEATS", "path": "using-explain.html", "label": "PostgreSQL 18.6 \u00b7 using-explain", "sha256": "60040c30180093418a0affe56dd27dff9df2504b705b38039589e458bf5c31ed", "language": "en", "original_url": "/docs/18/using-explain.html#USING-EXPLAIN-CAVEATS"}, {"url": "https://pg.center/docs/18/parallel-plans.html#PARALLEL-APPEND", "path": "parallel-plans.html", "label": "PostgreSQL 18.6 \u00b7 parallel-plans", "sha256": "62207d207bead82b01b59dc119c4f95856f08655cc11d4699a05a40867ed2070", "language": "en", "original_url": "/docs/18/parallel-plans.html#PARALLEL-APPEND"}, {"url": "https://pg.center/docs/18/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 18.6 \u00b7 using-explain", "sha256": "60040c30180093418a0affe56dd27dff9df2504b705b38039589e458bf5c31ed", "language": "en", "original_url": "/docs/18/using-explain.html#USING-EXPLAIN-ANALYZE"}], "node_tag": "T_Append", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aAppend.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u672c\u6b21\u62bd\u53d6\u4e0d\u4e3a\u6b64\u8282\u70b9\u8bbe\u5b9a\u7edf\u4e00\u7684\u5185\u5b58\u4e0a\u9650\u6216\u843d\u76d8\u7b56\u7565\u3002\u8bf7\u67e5\u770b\u540c\u4e00\u6784\u5efa\u7684\u5b9e\u73b0\u3001\u76f8\u5173\u8868\u8fbe\u5f0f\u6216\u63d0\u4f9b\u65b9\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1aExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM."]}, {"title": "\u540c\u7248\u672c\u624b\u518c\u8bf4\u660e", "paragraphs": ["\u901a\u5e38 EXPLAIN \u663e\u793a\u89c4\u5212\u5668\u521b\u5efa\u7684\u6bcf\u4e2a\u8282\u70b9\u3002\u4f46\u6267\u884c\u5668\u6709\u65f6\u53ef\u4ee5\u6839\u636e\u89c4\u5212\u9636\u6bb5\u5c1a\u4e0d\u53ef\u77e5\u7684\u53c2\u6570\u503c\uff0c\u5224\u5b9a\u67d0\u4e9b\u8282\u70b9\u65e0\u6cd5\u4ea7\u751f\u4efb\u4f55\u884c\uff0c\u56e0\u6b64\u4e0d\u5fc5\u6267\u884c\u3002\uff08\u76ee\u524d\u4ec5\u4f1a\u53d1\u751f\u5728\u626b\u63cf\u5206\u533a\u8868\u7684 Append \u6216 MergeAppend \u8282\u70b9\u7684\u5b50\u8282\u70b9\u4e0a\u3002\uff09\u6b64\u65f6 EXPLAIN \u7701\u7565\u8fd9\u4e9b\u8282\u70b9\uff0c\u6539\u4e3a\u663e\u793a Subplans Removed: N\u3002", "\u6bcf\u5f53 PostgreSQL \u9700\u8981\u5c06\u6765\u81ea\u591a\u4e2a\u6e90\u7684\u884c\u5408\u5e76\u6210\u4e00\u4e2a\u7ed3\u679c\u96c6\u65f6\uff0c\u5b83\u5c31\u4f1a\u4f7f\u7528 Append \u6216 MergeAppend \u8ba1\u5212\u8282\u70b9\u3002\u8fd9\u79cd\u60c5\u51b5\u5e38\u89c1\u4e8e\u5b9e\u73b0 UNION ALL \u6216\u626b\u63cf\u5206\u533a\u8868\u65f6\u3002\u8fd9\u6837\u7684\u8282\u70b9\u548c\u5176\u4ed6\u4efb\u4f55\u8ba1\u5212\u4e2d\u7684\u60c5\u5f62\u4e00\u6837\uff0c\u4e5f\u53ef\u4ee5\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u3002\u4e0d\u8fc7\uff0c\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\uff0c\u89c4\u5212\u5668\u4e5f\u53ef\u80fd\u6539\u7528 Parallel Append \u8282\u70b9\u3002", "\u5f53 Append \u8282\u70b9\u7528\u4e8e\u5e76\u884c\u8ba1\u5212\u65f6\uff0c\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u4f1a\u6309\u7167\u5b50\u8ba1\u5212\u51fa\u73b0\u7684\u987a\u5e8f\u6267\u884c\u5b83\u4eec\uff0c\u56e0\u6b64\u6240\u6709\u53c2\u4e0e\u8fdb\u7a0b\u4f1a\u534f\u4f5c\u6267\u884c\u7b2c\u4e00\u4e2a\u5b50\u8ba1\u5212\u76f4\u5230\u5176\u5b8c\u6210\uff0c\u7136\u540e\u518d\u5927\u81f4\u540c\u65f6\u8f6c\u5411\u7b2c\u4e8c\u4e2a\u5b50\u8ba1\u5212\u3002\u800c\u5f53\u4f7f\u7528 Parallel Append \u65f6\uff0c\u6267\u884c\u5668\u4f1a\u5c3d\u53ef\u80fd\u5747\u5300\u5730\u5c06\u53c2\u4e0e\u8fdb\u7a0b\u5206\u6563\u5230\u5404\u4e2a\u5b50\u8ba1\u5212\u4e0a\uff0c\u4ece\u800c\u4f7f\u591a\u4e2a\u5b50\u8ba1\u5212\u80fd\u591f\u540c\u65f6\u6267\u884c\u3002\u8fd9\u6837\u65e2\u907f\u514d\u4e86\u4e89\u7528\uff0c\u4e5f\u907f\u514d\u8ba9\u90a3\u4e9b\u4ece\u672a\u6267\u884c\u67d0\u4e2a\u5b50\u8ba1\u5212\u7684\u8fdb\u7a0b\u627f\u62c5\u5176\u542f\u52a8\u4ee3\u4ef7\u3002", "\u6b64\u5916\uff0c\u4e0e\u5728\u5e76\u884c\u8ba1\u5212\u4e2d\u53ea\u80fd\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\u7684\u666e\u901a Append \u8282\u70b9\u4e0d\u540c\uff0cParallel Append \u8282\u70b9\u65e2\u53ef\u5305\u542b\u90e8\u5206\u5b50\u8ba1\u5212\uff0c\u4e5f\u53ef\u5305\u542b\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u3002\u975e\u90e8\u5206\u5b50\u8ba1\u5212\u53ea\u7531\u4e00\u4e2a\u8fdb\u7a0b\u626b\u63cf\uff0c\u56e0\u4e3a\u591a\u6b21\u626b\u63cf\u4f1a\u4ea7\u751f\u91cd\u590d\u7ed3\u679c\u3002\u56e0\u6b64\uff0c\u5373\u4f7f\u6ca1\u6709\u9ad8\u6548\u7684\u90e8\u5206\u8ba1\u5212\uff0c\u62fc\u63a5\u591a\u4e2a\u7ed3\u679c\u96c6\u7684\u8ba1\u5212\u4e5f\u80fd\u5b9e\u73b0\u7c97\u7c92\u5ea6\u5e76\u884c\u3002\u4f8b\u5982\uff0c\u9488\u5bf9\u5206\u533a\u8868\u7684\u67e5\u8be2\uff0c\u53ef\u80fd\u53ea\u6709\u501f\u52a9\u4e0d\u652f\u6301\u5e76\u884c\u626b\u63cf\u7684\u7d22\u5f15\u624d\u80fd\u9ad8\u6548\u6267\u884c\u3002\u89c4\u5212\u5668\u53ef\u80fd\u9009\u62e9\u4f7f\u7528 Parallel Append \u62fc\u63a5\u591a\u4e2a\u666e\u901a Index Scan \u8ba1\u5212\uff1b\u6bcf\u6b21\u7d22\u5f15\u626b\u63cf\u90fd\u5fc5\u987b\u7531\u5355\u4e2a\u8fdb\u7a0b\u5b8c\u6574\u6267\u884c\uff0c\u4f46\u4e0d\u540c\u626b\u63cf\u53ef\u4ee5\u7531\u4e0d\u540c\u8fdb\u7a0b\u540c\u65f6\u6267\u884c\u3002"]}, {"title": "\u672c\u7248\u624b\u518c\u4e2d\u7684\u793a\u4f8b", "blocks": [{"code": "EXPLAIN UPDATE gtest_parent SET f1 = CURRENT_DATE WHERE f2 = 101;\n\n                                       QUERY PLAN\n----------------------------------------------------------------------------------------\n Update on gtest_parent  (cost=0.00..3.06 rows=0 width=0)\n   Update on gtest_child gtest_parent_1\n   Update on gtest_child2 gtest_parent_2\n   Update on gtest_child3 gtest_parent_3\n   ->  Append  (cost=0.00..3.06 rows=3 width=14)\n         ->  Seq Scan on gtest_child gtest_parent_1  (cost=0.00..1.01 rows=1 width=14)\n               Filter: (f2 = 101)\n         ->  Seq Scan on gtest_child2 gtest_parent_2  (cost=0.00..1.01 rows=1 width=14)\n               Filter: (f2 = 101)\n         ->  Seq Scan on gtest_child3 gtest_parent_3  (cost=0.00..1.01 rows=1 width=14)\n               Filter: (f2 = 101)", "source": {"url": "/docs/18/using-explain.html#USING-EXPLAIN-ANALYZE", "path": "using-explain.html", "label": "PostgreSQL 18.6 \u00b7 using-explain", "sha256": "60040c30180093418a0affe56dd27dff9df2504b705b38039589e458bf5c31ed"}, "paragraphs": ["\u793a\u4f8b\u6458\u81ea PostgreSQL 18.6 \u624b\u518c\uff1b\u672c\u767e\u79d1\u672a\u5b9e\u9645\u6267\u884c\u6b64\u793a\u4f8b\u3002", "\u5f53 UPDATE \u3001 DELETE \u6216 MERGE \u547d\u4ee4\u5f71\u54cd\u5206\u533a\u8868\u6216\u7ee7\u627f\u5c42\u6b21\u65f6\uff0c\u8f93\u51fa\u53ef\u80fd\u50cf\u8fd9\u6837\uff1a"]}]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["\u8bf4\u660e\uff1a\u6bcf\u4e2a Append \u8282\u70b9\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u5fc5\u987b\u9010\u4e00\u5904\u7406\u7684\u5b50\u8ba1\u5212\uff0c\u65b9\u5411\u53ef\u4ee5\u6b63\u5411\u6216\u53cd\u5411\u3002\u6267\u884c\u7b2c whichplan \u4e2a\u5b50\u8ba1\u5212\u53d6\u56de\u5143\u7ec4\uff0c\u76f4\u5230\u5b83\u4e0d\u518d\u8fd4\u56de\u5143\u7ec4\uff0c\u7136\u540e\u5173\u95ed\u8be5\u8ba1\u5212\u5e76\u542f\u52a8\u4e0b\u4e00\u4e2a\u3002", "Append \u8282\u70b9\u4e0d\u4f7f\u7528\u5de6\u3001\u53f3\u5b50\u6811\uff0c\u800c\u662f\u7ef4\u62a4\u4e00\u4e2a\u5b50\u8ba1\u5212\u5217\u8868\uff0c\u56e0\u6b64\u5178\u578b\u7684 Append \u8282\u70b9\u5728\u8ba1\u5212\u6811\u4e2d\u5982\u4e0b\u6240\u793a\uff1a", "... / Append -------+------+------+--- nil / \\ | | | nil nil ... ... ... subplans", "Append \u8282\u70b9\u76ee\u524d\u7528\u4e8e\u5e76\u96c6\u64cd\u4f5c\uff0c\u4e5f\u7528\u4e8e\u9700\u8981\u626b\u63cf\u591a\u4e2a\u5173\u7cfb\u7684\u7ee7\u627f\u67e5\u8be2\u3002\u4f8b\u5982\uff0c\u5728\u6807\u51c6\u7684 person/student/employee/student-emp \u793a\u4f8b\u4e2d\uff0cstudent \u548c employee \u7ee7\u627f\u81ea person\uff0c\u800c student-emp \u540c\u65f6\u7ee7\u627f\u81ea student \u548c employee\uff0c\u67e5\u8be2\u5982\u4e0b\uff1a", "| Append -------+-------+--------+--------+ / \\ | | | | nil nil Scan Scan Scan Scan | | | | person employee student student-emp"]}, {"code": "case T_Append:\n\t\t\tpname = sname = \"Append\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u904d\u5386\u5404\u5b50\u8ba1\u5212\u5e76\u5408\u5e76\u5176\u8f93\u51fa\u884c\u3002"], "localization": {"status": "complete", "sources": [{"url": "/docs/18/parallel-plans.html", "method": "same-major semantic node", "sha256": "7fa104623c0b4cd22acf0929e40518fbed8fe368af3e3b124cf693bd7ab69f0c", "language": "zh", "matched_nodes": ["#PARALLEL-PLANS/div[6]/p[1]", "#PARALLEL-PLANS/div[6]/p[2]"]}, {"url": "/docs/18/using-explain.html", "method": "same-major semantic node", "sha256": "b8835ec9adbc70ec150667a6b5443f8d298222dc0cc8c2bd1abb1c1d64895904", "language": "zh", "matched_nodes": ["#USING-EXPLAIN/div[8]/p[29]"]}], "language": "zh", "original_text": {"/versions/18/description/0": "Visits its child plans and combines their rows.", "/versions/18/facts/0/label": "Core node tag", "/versions/18/facts/1/label": "Structured EXPLAIN Node Type", "/versions/18/facts/2/label": "Inputs", "/versions/18/facts/2/value": "Multiple child plans", "/versions/18/facts/3/label": "Output", "/versions/18/facts/3/value": "Combined tuples", "/versions/18/facts/4/label": "Executor initializer", "/versions/18/facts/5/label": "Memory mechanism", "/versions/18/tables/0/title": "EXPLAIN labels in this source build", "/versions/18/related/1/label": "Using EXPLAIN", "/versions/18/related/2/label": "Parallel plans", "/versions/18/sections/0/title": "EXPLAIN names and attributes", "/versions/18/sections/1/title": "Memory and temporary storage", "/versions/18/sections/2/title": "Parallel execution and instrumentation", "/versions/18/sections/3/title": "Same-version manual discussion", "/versions/18/sections/4/title": "Examples from this manual build", "/versions/18/sections/5/title": "Executor implementation notes", "/versions/18/sections/6/title": "EXPLAIN identity in core source", "/versions/18/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.", "/versions/18/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/18/sections/0/paragraphs/1": "Text names recorded by this source: Append.", "/versions/18/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/18/sections/1/paragraphs/0": "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.", "/versions/18/sections/2/paragraphs/0": "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.", "/versions/18/sections/2/paragraphs/1": "Callbacks in this build: ExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM.", "/versions/18/sections/3/paragraphs/0": "Normally, EXPLAIN will display every plan node created by the planner. However, there are cases where the executor can determine that certain nodes need not be executed because they cannot produce any rows, based on parameter values that were not available at planning time. (Currently this can only happen for child nodes of an Append or MergeAppend node that is scanning a partitioned table.) When this happens, those plan nodes are omitted from the EXPLAIN output and a Subplans Removed: N annotation appears instead.", "/versions/18/sections/3/paragraphs/1": "Whenever PostgreSQL needs to combine rows from multiple sources into a single result set, it uses an Append or MergeAppend plan node. This commonly happens when implementing UNION ALL or when scanning a partitioned table. Such nodes can be used in parallel plans just as they can in any other plan. However, in a parallel plan, the planner may instead use a Parallel Append node.", "/versions/18/sections/3/paragraphs/2": "When an Append node is used in a parallel plan, each process will execute the child plans in the order in which they appear, so that all participating processes cooperate to execute the first child plan until it is complete and then move to the second plan at around the same time. When a Parallel Append is used instead, the executor will instead spread out the participating processes as evenly as possible across its child plans, so that multiple child plans are executed simultaneously. This avoids contention, and also avoids paying the startup cost of a child plan in those processes that never execute it.", "/versions/18/sections/3/paragraphs/3": "Also, unlike a regular Append node, which can only have partial children when used within a parallel plan, a Parallel Append node can have both partial and non-partial child plans. Non-partial children will be scanned by only a single process, since scanning them more than once would produce duplicate results. Plans that involve appending multiple result sets can therefore achieve coarse-grained parallelism even when efficient partial plans are not available. For example, consider a query against a partitioned table that can only be implemented efficiently by using an index that does not support parallel scans. The planner might choose a Parallel Append of regular Index Scan plans; each individual index scan would have to be executed to completion by a single process, but different scans could be performed at the same time by different processes.", "/versions/18/sections/5/paragraphs/0": "NOTES Each append node contains a list of one or more subplans which must be iteratively processed (forwards or backwards). Tuples are retrieved by executing the 'whichplan'th subplan until the subplan stops returning tuples, at which point that plan is shut down and the next started up.", "/versions/18/sections/5/paragraphs/1": "Append nodes don't make use of their left and right subtrees, rather they maintain a list of subplans so a typical append node looks like this in the plan tree:", "/versions/18/sections/5/paragraphs/3": "Append nodes are currently used for unions, and to support inheritance queries, where several relations need to be scanned. For example, in our standard person/student/employee/student-emp example, where student and employee inherit from person and student-emp inherits from student and employee, the query:", "/versions/18/tables/0/columns/0/label": "Text-format label", "/versions/18/tables/0/columns/1/label": "Structured node identity", "/versions/18/sections/4/blocks/0/paragraphs/0": "Example copied from the PostgreSQL 18.6 manual; it was not executed for this collection.", "/versions/18/sections/4/blocks/0/paragraphs/1": "When an UPDATE , DELETE , or MERGE command affects a partitioned table or inheritance hierarchy, the output might look like this:"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "98705531ccd5bf753c83a0014cdbc4177f98a28d39a55e2a9e84947e2eb77640"}, "evidence_kind": "source and documentation", "explain_names": ["Append"], "partial_modes": [], "comparison_data": {"node_tag": "T_Append", "strategies": [], "text_names": ["Append"], "initializer": "ExecInitAppend", "partial_modes": [], "memory_mechanism": "unclassified", "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "comparison_hash": "05fc087ef5a99b9d2d14f9b7e397d941085dafd8c263de24871ec9926b47ad8f", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeAppend.c"}, "parallel_callbacks": ["ExecAppendEstimate", "ExecAppendInitializeDSM", "ExecAppendInitializeWorker", "ExecAppendReInitializeDSM"]}, "comparison": {"left": "10", "right": "11", "status": "changed", "diff": "--- PostgreSQL 10\n+++ PostgreSQL 11\n@@ -2,7 +2,12 @@\n   \"initializer\": \"ExecInitAppend\",\n   \"memory_mechanism\": \"unclassified\",\n   \"node_tag\": \"T_Append\",\n-  \"parallel_callbacks\": [],\n+  \"parallel_callbacks\": [\n+    \"ExecAppendEstimate\",\n+    \"ExecAppendInitializeDSM\",\n+    \"ExecAppendInitializeWorker\",\n+    \"ExecAppendReInitializeDSM\"\n+  ],\n   \"partial_modes\": [],\n   \"strategies\": [],\n   \"text_names\": ["}}