Limit
Limit
将执行计划的行数限制和偏移量应用于子计划输出。
当前查看 PostgreSQL 18.6。
说明
将执行计划的行数限制和偏移量应用于子计划输出。
- 核心节点标签
- T_Limit
- 结构化 EXPLAIN 节点类型
- Limit
- 输入
- 一个子计划
- 输出
- 选定范围的元组
- 执行器初始化函数
- ExecInitLimit
- 内存机制
- unclassified
EXPLAIN 名称与属性
结构化格式使用上述 Node Type。文本格式名称还可能包含操作、策略、连接类型、扫描方向或聚合阶段属性。
此源码记录的文本名称:Limit.
并行感知与并行安全是不同的计划属性。在并行工作进程内运行的节点不一定是并行感知节点。
内存与临时存储
本次抽取不为此节点设定统一的内存上限或落盘策略。请查看同一构建的实现、相关表达式或提供方。
并行执行与运行信息采集
以下源码回调可以协调执行或收集工作进程的测量数据。回调存在不代表该节点普遍支持共享并行扫描或共享状态。
此构建的回调:none extracted from this node implementation.
同版本手册说明
估计总代价:假定计划节点完整执行,即取出所有可用行时的代价。实际执行时,父节点可能尚未读取全部可用行就提前停止(见下方 LIMIT 示例)。
与普通排序相比,增量排序可在整个结果集尚未排完时就返回元组,尤其有利于优化带 LIMIT 的查询。它还可能减少内存用量和排序溢写磁盘的概率,但代价是将结果集拆成多个排序批次所带来的额外开销。
查询与上例相同,只是增加 LIMIT,不再需要取回全部行,因此规划器改变了选择。Index Scan 节点的总成本和行数仍按完整执行显示,但 Limit 预计只取回五分之一的行就停止,其总成本也只有五分之一,这才是查询的实际估计成本。与在此前计划上添加 Limit 相比,此计划更优,因为 Limit 无法避免位图扫描的启动成本,原方案的总成本仍会超过 25 个单位。
实际值与估计值有时并不吻合,但并不表示有问题。例如 LIMIT 或类似作用提前停止计划节点执行时就会如此。以前面的 LIMIT 查询为例:
Index Scan 节点的估计成本和行数按完整执行显示。但实际执行中,Limit 在取得两行后就不再请求,因此实际行数仅为 2,运行时间也低于成本估计所暗示的值。这不是估计错误,只是估计值与实际值的展示口径不同。
归并连接的测量结果也可能产生误导。若一侧输入已耗尽,另一侧的下一个键值又大于已耗尽输入的最后一个键值,就不会再有匹配,因此会停止读取另一侧。这样便未读取该子节点的全部行,类似 LIMIT 的情况。另外,外侧(第一个)子节点有重复键值时,内侧(第二个)子节点会回退并重新扫描匹配该键值的行。EXPLAIN ANALYZE 会将内侧重复输出的行计作额外的真实行。因此外侧重复值很多时,内侧计划节点报告的实际行数可能显著超过内侧关系中的实际行数。
本版手册中的示例
示例摘自 PostgreSQL 18.6 手册;本百科未实际执行此示例。
如果计划中的某一部分已经保证了所需排序键前缀的顺序,规划器也可能改用 Incremental Sort 步骤:
EXPLAIN SELECT * FROM tenk1 ORDER BY hundred, ten LIMIT 100;
QUERY PLAN
------------------------------------------------------------------------------------------------
Limit (cost=19.35..39.49 rows=100 width=244)
-> Incremental Sort (cost=19.35..2033.39 rows=10000 width=244)
Sort Key: hundred, ten
Presorted Key: hundred
-> Index Scan using tenk1_hundred on tenk1 (cost=0.29..1574.20 rows=10000 width=244)示例摘自 PostgreSQL 18.6 手册;本百科未实际执行此示例。
下面的示例展示 LIMIT 的作用:
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2;
QUERY PLAN
-------------------------------------------------------------------------------------
Limit (cost=0.29..14.28 rows=2 width=244)
-> Index Scan using tenk1_unique2 on tenk1 (cost=0.29..70.27 rows=10 width=244)
Index Cond: (unique2 > 9000)
Filter: (unique1 < 100)执行器实现说明
nodeLimit.c:在适当情况下限制查询结果的例程。
这是一个非常简单的节点,仅对某个子计划返回的元组流执行 LIMIT/OFFSET 筛选。
首次调用此节点,因此计算 limit/offset。(不能更早计算,因为 ExecInitLimit 阶段尚未设置上层节点传来的参数。)这还会设置 position = 0,并将状态改为 LIMIT_RESCAN。
子计划返回的元组太少,无法产生任何输出。
需要保存边界处的元组,以在后续执行中比较并识别并列值。
核心源码中的 EXPLAIN 标识
case T_Limit:
pname = sname = "Limit";
break;本构建中的 EXPLAIN 标签
| 文本格式标签 | 结构化节点标识 |
|---|---|
| Limit | Limit |
相关条目
文档与源码
- src/backend/commands/explain.c:1601
- src/backend/executor/execProcnode.c:380
- src/backend/executor/nodeLimit.c
- src/include/nodes/plannodes.h
- PostgreSQL 18.6 · using-explain
- PostgreSQL 18.6 · using-explain
来源构建
- 版本
- 18.6
- 构建
- PostgreSQL 18.6 source archive
- 来源指纹
555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f
版本比较
PostgreSQL 17 → 18: 无变化。
比较已记录的接口与属性,排除来源指纹和构建元数据。某个样本中没有记录,不能据此判断实际引入或移除的版本。
相关条目
LockRowsLockRowsProjectSetProjectSetResultResult
导出 JSON · 返回执行计划节点 · 收录范围为 PostgreSQL 10 至 20;最早采样版本不一定是实际引入版本。