news 2026/6/13 12:31:27

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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 提供实时分析、可视化、事件管理与报警等功能。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/13 12:29:19

Adobe-GenP终极指南:3分钟完成Adobe全家桶激活的完整方案

Adobe-GenP终极指南:3分钟完成Adobe全家桶激活的完整方案 【免费下载链接】Adobe-GenP Adobe CC 2019/2020/2021/2022/2023 GenP Universal Patch 3.0 项目地址: https://gitcode.com/gh_mirrors/ad/Adobe-GenP Adobe-GenP是一款强大的Adobe Creative Cloud通…

作者头像 李华
网站建设 2026/6/13 12:28:07

抖音无水印下载神器:douyin-downloader完整指南

抖音无水印下载神器:douyin-downloader完整指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support. 抖…

作者头像 李华
网站建设 2026/6/13 12:24:05

《剑与翼》下载安装全流程指南 兼容性预检与故障排查手册

文章摘要 针对魔幻怀旧 MMO 玩家在剑与翼下载安装过程中遇到的设备不兼容、安装包损坏、启动异常、资源加载失败等高频问题,本文从下载前设备兼容性自查、正规安装包筛选校验、分端标准化安装、首次启动性能调试、常见故障一站式解决五个维度展开,整理了…

作者头像 李华
网站建设 2026/6/13 12:24:02

多智能体循环迭代与安全防护修复

最近几天集中把剩余的高优先级Bug清理了一遍,主要是三个方向的工作:多智能体协作加了反馈循环机制、前端修了XSS漏洞、后端补了限流和类型一致性 一、开发目标 为多智能体协作流程增加CriticAgent反馈循环,让SQL生成质量可迭代提升修复前端ch…

作者头像 李华
网站建设 2026/6/13 12:23:23

基于Java Spring Boot的人脸识别签到系统

一、项目简介功能描述:本项目基于Java Spring Boot开发人脸识别签到系统,接入阿里云人脸比对API与OSS对象存储实现云端高精度人脸识别,同时自研多特征人脸比对算法作为离线降级方案,整合图像解析、文件读写、前后端交互等功能&…

作者头像 李华