当前位置: 首页 > news >正文

TDengine 物理计划生成 — 算子下沉、Exchange 与 Subplan 切分

分类:4.查询引擎 |篇章:05 物理计划

适用版本:TDengine v3.x(v3.3.x / v3.4.x) | 最后更新:2026-06-12

物理计划(Physical Plan)将逻辑算子映射为具体的物理算子实现,确定算子的执行节点(VNode/QNode/Client),插入 Exchange 节点完成数据流转,最终输出可被 Scheduler 直接调度的 Subplan 集合。

核心概念速查表

概念说明
Physical Operator物理算子(Table Scan、Hash Agg、Merge Join 等)
Subplan一个执行单元,对应一个节点(VNode/QNode)的任务
Exchange Operator跨节点数据传输算子
DataSinkSubplan 的输出端,将数据发给上层
DAGSubplan 之间形成的有向无环图
Two-Phase Aggregation两阶段聚合(Partial + Final)

详细解析

1. 物理算子分类

TDengine 主要物理算子: 扫描类: - TableScan / TagScan / SystemTableScan - StreamScan 过滤投影: - Filter / Project 聚合类: - Hash Aggregate(GROUP BY) - Stream Aggregate(已排序数据流式聚合) - Partial / Final Aggregate(两阶段) 窗口类: - Interval Window - Session Window - State Window - Event Window - Count Window 排序合并: - Sort / Merge / SortMerge 连接类: - Hash Join / Merge Join / Nested Loop Join 数据流: - Exchange(接收) - DataDispatch(发送)

2. 逻辑算子到物理算子的映射

逻辑算子候选物理算子选择依据
LogicScanTableScan / TagScan是否只查 Tag
LogicFilterFilter通用
LogicAggHashAgg / StreamAgg输入是否已排序
LogicWindowIntervalWindow / SessionWindow窗口类型
LogicSortSort / MergeSort输入是否多路
LogicJoinHashJoin / MergeJoin数据量与排序性

3. 两阶段聚合下沉

SELECT location, AVG(current) FROM meters GROUP BY location 逻辑计划: LogicAgg (GROUP BY location, AVG(current)) └── LogicScan (meters) 物理计划(两阶段): ┌─ Subplan 0 (Client/QNode) ─────────────────┐ │ Final Aggregate │ │ AVG = SUM(partial_sum) / SUM(partial_cnt)│ │ ↑ │ │ Exchange ← 接收 Subplan 1/2/N 的结果 │ └────────────────────────────────────────────┘ ▲ ┌───────────┼───────────┬─────────────┐ │ │ │ │ ┌─ Subplan 1 ─┐ ┌─ Subplan 2 ─┐ ┌─ Subplan N ─┐ │ DataSink │ │ DataSink │ │ DataSink │ │ Partial Agg │ │ Partial Agg │ │ Partial Agg │ │ SUM(c), │ │ SUM(c), │ │ SUM(c), │ │ COUNT(*) │ │ COUNT(*) │ │ COUNT(*) │ │ TableScan │ │ TableScan │ │ TableScan │ └─────────────┘ └─────────────┘ └─────────────┘ (VNode 1) (VNode 2) (VNode N) 优势: - VNode 内本地聚合,输出从万行减少到几行 - Exchange 传输量极小 - Final 聚合开销低

4. Exchange 算子的工作模式

Exchange 的三种数据传输模式: ① ShuffleExchange(按 Key 重分发): 场景:跨节点 GROUP BY 大量分组键 行为:发送端按 Key Hash 决定接收方 接收端按 Key 收集到对应桶 ② PartitionExchange(保持分区): 场景:PARTITION BY tbname 行为:每个子表的数据完整发到同一接收端 接收端独立计算每个分区 ③ MergeExchange(按序合并): 场景:跨节点 ORDER BY ts 行为:每个 VNode 内已按 ts 排序 接收端做 K-way Merge 选择策略: - 数据已有序 + 需要全局有序 → MergeExchange - 按 Key 分组 → ShuffleExchange - 按分区独立处理 → PartitionExchange

5. Subplan 切分规则

Subplan 边界的判定: 规则:算子需要跨节点数据 → 插入 Exchange → 切分 Subplan 示例: SELECT location, AVG(current) FROM meters WHERE ts > now-1h GROUP BY location Subplan 切分: Subplan 0 (Client) Final Aggregate Exchange (接收 Subplan 1~N) Subplan 1 (VNode 1) DataSink (发到 Subplan 0) Partial Aggregate Filter (ts > now-1h) TableScan (meters, vgId=1) Subplan 2 (VNode 2) DataSink (发到 Subplan 0) Partial Aggregate Filter (ts > now-1h) TableScan (meters, vgId=2) ... 直到所有 VGroup

6. 时序专属物理算子

INTERVAL 窗口物理算子选择: SELECT _wstart, COUNT(*) FROM meters INTERVAL(1h) 数据已按 ts 排序的优势: ① StreamIntervalWindow(流式): - 输入按 ts 有序 - 维护当前窗口状态 - ts 跨入新窗口 → 输出当前窗口结果 - 内存占用 O(1)(只保留当前窗口) vs HashIntervalWindow: - 输入无序时使用 - 用哈希表保存所有未关闭窗口 - 内存占用 O(N)(N = 窗口数) TDengine 优先选择 StreamIntervalWindow(数据天然有序) SESSION/STATE 窗口: - 必须按 ts 顺序扫描 - 边界由数据内容决定(不是固定时间) - 算子维护当前会话/状态

7. 限制性子句的物理实现

LIMIT 与 OFFSET: LIMIT N 下推: SELECT * FROM meters LIMIT 10 → 每个 VNode 各取 10 行(Partial LIMIT) → Exchange 接收最多 10*N 行 → Final 阶段 LIMIT 10 ORDER BY + LIMIT 优化: SELECT * FROM meters ORDER BY ts DESC LIMIT 10 → 每个 VNode 内有序 → 取最后 10 行 → Exchange 阶段 K-way Merge 取前 10 → 无需全量排序 OFFSET 的代价: OFFSET 1000000 → 需要先读取并丢弃前 100 万行 → 大 OFFSET 性能极差 → 推荐用时间范围或 Tag 过滤代替分页

8. 不同查询类型的物理计划差异

查询类型物理特点
单子表点查单 Subplan,无 Exchange
单超级表无聚合跨 VGroup Scan + Merge
单超级表聚合两阶段 Agg + Exchange
跨库 JOINHash Join + 多 Subplan
窗口聚合StreamWindow + 两阶段
嵌套子查询多层 Exchange

代码示例

查看物理计划

EXPLAINVERBOSESELECTlocation,AVG(current)FROMmetersWHEREts>now-1hGROUPBYlocation;-- 输出会显示:-- - Subplan 0: AggregateMerge + ExchangeReceiver-- - Subplan 1..N: AggregatePartial + TableScan

强制使用 QNode

-- 提示查询使用 QNode(如果集群配置了)SELECT/*+ USE_QNODE */COUNT(*)FROMbig_table;

观察 Exchange 数据量

EXPLAINANALYZESELECTlocation,COUNT(*)FROMmetersGROUPBYlocation;-- 关注 Exchange 节点的:-- - rows_input: 接收的行数-- - bytes_input: 接收的字节数-- → 越小说明 Partial Agg 越有效

性能考量

Subplan 数量对性能的影响

Subplan 数适用场景注意
1单子表点查最简单,无网络开销
数十中等规模聚合平衡并行度与协调开销
数百大规模分析调度开销可能成为瓶颈
数千不推荐应考虑预聚合或分批查询

Exchange 优化要点

要点说明
尽量在叶子节点 Partial Agg减少 Exchange 数据量
利用数据有序性用 MergeExchange 替代 Sort
避免无谓的全量传输LIMIT/Tag 过滤下推

FAQ

Q1: 为什么我的查询只有一个 Subplan?

可能原因:

  • 只查一个子表(命中单一 VGroup)
  • 时间范围内只有一个 VGroup 有数据
  • 使用了不分区的 META 表查询

这是高效的——无 Exchange 开销。

Q2: 两阶段聚合一定更快吗?

大部分情况是。但极端场景(如分组键基数巨大且无重复,Partial Agg 无收益)可能反而增加开销。规划器会根据估算决定是否启用。

Q3: 物理计划缓存吗?

参数化查询(STMT)的物理计划会被复用。普通文本 SQL 每次都重新生成。如需高频执行相同结构的查询,强烈推荐使用 STMT。

Q4: 能手动控制 Subplan 切分吗?

目前不支持直接干预。可以通过 hint(如USE_QNODE)影响算子放置,或通过改写 SQL(如 CTE/子查询)间接影响。

参考

系统构架篇

  • 01-《TDengine 整体架构全景》
  • 02-《集群拓扑深度解析》
  • 03-《MNode 内部机制深度解析》
  • 04-《RPC 通信层深度解析》
  • 05-《VNode 生命周期》
  • 06-《RAFT 共识协议》
  • 07-《端到端的消息流》

数据模型

  • 01-《数据库创建与参数详解》
  • 02-《超级表/子表/普通表》
  • 03-《支持数据类型深度解析》
  • 04-《TDengine Tag 设计哲学与 Schema 变更机制》
  • 05-《TDengine 虚拟表实现原理》

存储引擎

  • 01-《TDengine 存储引擎概览》
  • 02-《TDengine MemTable 深度解析》
  • 03-《TDengine WAL 预写日志机制》
  • 04-《TDengine 数据文件格式》
  • 05-《TDengine Commit 与 Flush 机制 》
  • 06-《TDengine Compaction 合并策略 》
  • 07-《TDengine 数据保留与 TTL》
  • 08-《TDengine 压缩编码机制》
  • 09-《TDengine Cache 与 Last 查询加速》
  • 10-《TDengine 逻辑计划生成》

查询引擎

  • 01-《TDengine 查询引擎概览》
  • 02-《TDengine SQL 解析与词法分析》
  • 03-《TDengine 语义分析与 AST 重写》
  • 04-《TDengine 语义分析与 AST 重写》

关于 TDengine

TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。

http://www.zskr.cn/news/1517104.html

相关文章:

  • 2026迪庆市江诗丹顿+万国手表专业回收,26年精选回收店铺排行榜推荐 - 谊识预商务
  • 2026平顶山市迪奥、古驰、普拉达包包专业回收,2026甄选回收店铺排行榜推荐 - 谊识预商务
  • AI Agent 的沙箱是什么?它和 Docker / 虚拟机有什么区别?
  • 2026赣州市帝舵+浪琴手表专业回收,26年精选回收店铺排行榜推荐 - 谊识预商务
  • 纵横京津冀长三角粤港澳,法兰迪无机隧道涂料护航深圳春风、无锡竺山湖、深中通道等10余个标杆工程
  • 从焊接M头到N型头:一份给火腿族的射频馈线接头升级指南
  • 3步掌握抖音批量下载工具:从零构建高效内容采集系统
  • 2026甘孜市朗格+积家手表专业回收,26年精选回收店铺排行榜推荐 - 谊识预商贸
  • 百度智能云X利尔达:产业“链接者”,铺设AI硬件万物生长之路
  • 2026焦作市百达翡丽+宝珀手表专业回收,26年精选回收店铺排行榜推荐 - 谊识预商贸
  • Auto-GPT实战:构建目标驱动的代码调试与修复闭环
  • 数字展厅与科技展厅解决方案的行业引领者
  • JCMsuite应用:光学环形谐振腔模拟
  • 终极微博图片批量下载指南:3步解决内容创作者的素材收集难题
  • 1、Mujoco安装和快捷键操作
  • 10分钟告别网页编辑噩梦:Chrome文本替换插件让你的工作效率飙升300%
  • 2026朝阳市卡地亚+GP芝柏表手表专业回收,26年精选回收店铺排行榜推荐 - 谊识预商贸
  • 2026嘉峪关市卡地亚+GP芝柏表手表专业回收,26年精选回收店铺排行榜推荐 - 谊识预商贸
  • 魔兽争霸3性能救星:如何让20年老游戏在现代电脑上流畅运行?
  • ENVI分类后处理实战:合并林地耕地、剔除空值,让你的土地利用专题图更‘干净’
  • 保姆级教程:手把手搭建Java靶场(JshERP 2.3)并复现Fastjson+MySQL JDBC反序列化漏洞
  • 【程序语言与编译】语法分析:自上而下推导(最左/最右)
  • 7个可测量的Prompt工程底层技巧:从指令解析到熵值控制
  • 2026总部看全局、区域看趋势、门店看自己:服装全渠道BI看板的三层架构
  • 如何快速搭建实时弹幕数据采集系统:跨平台直播监控终极方案
  • 2026申请香港身份怎么挑靠谱中介?3 家中介真实测评对比来了
  • Rust实战:轻量级IBC侧链验证器开发
  • 2026潮州市雅典+天梭手表专业回收,26年精选回收店铺排行榜推荐 - 莘州文化
  • 2026年磁致伸缩位移/液位传感器厂家:专业高精度磁致伸缩沉降检测仪器与传感器供应商 - 品牌发掘
  • 15-17岁还能长高吗?青少年二次追高窗口期,分年龄段追高指南