深度解析JQuick-SQL 逻辑计划到物理计划生成机制|分布式SQL原理

深度解析JQuick-SQL 逻辑计划到物理计划生成机制|分布式SQL原理

Meta 描述:本文基于jquick-sql架构原理解析JQuickPhysicalPlanGenerator如何把逻辑计划映射为可执行物理节点,涵盖Table Scan、Hash Join、Nested Loop Join、Hash Aggregate、Exchange与TopN,并说明Java分布式SQL引擎架构、SQL查询优化原理及gRPC分布式数据交换的衔接。

标签:jquick-sql架构原理、Physical Plan、JQuickPhysicalPlanGenerator、Hash Join、Hash Aggregate、gRPC分布式数据交换

官网示例:

前言

逻辑计划回答"查询由哪些关系操作组成",物理计划(Physical Plan)进一步回答"用哪些执行节点完成这些操作"。JQuick-SQL 中的 JQuickPhysicalPlanGenerator 负责这一映射;它接收 JQuickLogicalPlanNode,生成对应的 JQuickPhysicalPlanNode,然后调用物理优化器做进一步调整。

这一步是从 SQL查询优化原理走向执行实现的分界:逻辑层的 Join 不指定算法,物理层才选择 Hash Join 或 Nested Loop Join;逻辑层的 GroupBy 不指定交换方式,物理优化后才可能出现 Exchange 与两阶段聚合。

Generator入口与节点映射

生成入口为:

java 复制代码
public JQuickPhysicalPlanNode generate(JQuickLogicalPlanNode logicalPlan) {
    logicalPlan.accept(this);
    JQuickPhysicalPlanNode physicalPlan = logicalToPhysical.get(logicalPlan);
    if (physicalPlan != null) {
        physicalPlan = optimizer.optimize(physicalPlan);
    }
    return physicalPlan;
}

该实现先通过 Visitor 访问逻辑节点,再从映射表取得物理节点,最后执行 JQuickPhysicalPlanOptimizer。已确认的映射包括:TableScan → JQuickTableScanPhysicalNode、Filter → JQuickFilterPhysicalNode、Project → JQuickProjectPhysicalNode、Sort → JQuickSortPhysicalNode、Limit → JQuickLimitPhysicalNode,以及 Values、Empty、Window、Set Operation、Recursive Union 等节点。

Join:算法选择不写死在SQL里

处理 JQuickJoinNode 时,生成器会检查连接类型与连接条件。CROSS JOIN 或满足等值连接条件的 Join 可以构造成 JQuickHashJoinPhysicalNode;其构造参数包含 join type、左右 child、条件、join keys、build side、分布方式及别名。初始分布方式被设为 SHUFFLE_HASH,后续物理优化器会根据统计信息调整。

其他条件走 JQuickNestedLoopJoinPhysicalNode。因此,不应把"所有 JOIN 都是 Hash Join"当成项目事实:是否具备可提取的等值键会影响物理节点选择。

聚合、限制与物理优化

逻辑 GroupBy 会被转换为 JQuickHashAggregatePhysicalNode,初始阶段为 AggregateStage.SINGLE。之后物理优化器可能把大数据量且带 group keys 的聚合改写为 PARTIAL、SHUFFLE Exchange、FINAL 三段结构。

Limit 也不必保持原形。物理优化器发现 JQuickLimitPhysicalNode 的子节点为 JQuickSortPhysicalNode 时,会产生 JQuickTopNPhysicalNode。这表明 Generator 负责忠实映射逻辑语义,而优化器负责组合节点层面的执行改写。

Exchange与计划边界

JQuickExchangePhysicalNode 属于真实物理节点,保存 exchange type、partition strategy、partition keys、target parallelism 与 child。它继承 child 的输出 schema 与统计信息,本身不重新定义列结构。Exchange 为 Fragment 之间的数据再分布提供计划表示,是 Java分布式SQL引擎架构中连接本地算子和 gRPC 数据传输的关键桥梁。

text 复制代码
Logical Join / GroupBy
        ↓
JQuickPhysicalPlanGenerator
        ↓
Physical Nodes
        ↓
JQuickPhysicalPlanOptimizer
        ↓
Hash Join分布调整 / TopN / Exchange / 两阶段聚合

实操代码案例

README 的嵌入式模式可以触发完整执行管线:

java 复制代码
JQuickSQL sql = JQuickSQL.embedded();
try {
    sql.registerTable("users", columns, rows);
    JQuickDataSet result = sql.execute(
        "SELECT id, name, age FROM users WHERE age >= 25 ORDER BY age DESC"
    );
    result.printTable();
} finally {
    sql.shutdown();
}

该示例不直接暴露物理节点,但在内部链路中,扫描、过滤、投影、排序与执行均需经过计划生成。文档中的 embedded() 与 shutdown() 均为 README 已提供的真实接口。

常见问题

Physical Plan是否等于最终分布式任务?

不完全等于。物理计划之后还会经过 Fragmenter 切分,形成可调度的 Fragment。

为什么生成器后还要优化?

生成器完成逻辑到物理的基础映射;物理优化器再进行 Join 分布选择、两阶段聚合、TopN 与 Exchange 等改写。

Exchange会改变结果字段吗?

JQuickExchangePhysicalNode 的输出 schema 直接继承 child,重点是数据分发而不是列转换。

总结与拓展

JQuickPhysicalPlanGenerator 把逻辑语义落到实际执行节点,并把节点树交给物理优化器。其价值在于将 Scan、Filter、Project、Join、Aggregate、Sort、Limit 等操作落实为可执行结构,同时为 Exchange 与 Fragment 分布式调度留下明确接口。

Core Advantage

It separates logical semantics from executable algorithms and distribution decisions.

Applicable Scenarios

Physical-plan debugging, execution tuning, distributed planning, and operator development.

相关推荐
恒知学术5 小时前
时间序列异常检测论文怎么查?我把 3 轮检索和筛选表写成了可复现流程
数据库·文献检索·谷歌学术
小豆庄5 小时前
视频脱敏:云端识别与本地推理的边界实测
数据库·yolo·自然语言处理·视觉检测·视频·设计规范·纹理贴图
wshzd5 小时前
LLM之Agent(120)|DeepSeek-Harness(二十七)Workflow 引擎与 Ralph 循环
前端·数据库·人工智能
磁场转动100万匹5 小时前
Spark Core 核心原理:从 RDD 到分布式计算
大数据·分布式·spark
l1t5 小时前
DeepSeek总结的DuckDB 2.0.0 中的隐藏亮点
大数据·数据库·duckdb
程序员塔塔喵6 小时前
【MySQL篇|第八篇】索引底层实现
数据库·mysql·adb·索引
updayday8546 小时前
电脑换了硬盘、加了内存,资产台账却没更新 - Ping64 硬件资产管理
大数据·网络·数据库·安全·智能路由器
hhhjhl6 小时前
mime-types 跨端三方库仓颉适配全流程
数据库
广州智造6 小时前
Radioss中破坏模型FAILTAB1的详细介绍
数据库·人工智能·算法·机器学习·仿真软件·radioss