深度解析JQuick-SQL Join重排序与哈希连接执行机制
Meta 描述:本文从jquick-sql架构原理分析Join Reorder、Hash Join与Nested Loop Join的分工,说明JQuickPhysicalPlanGenerator如何依据等值条件选择物理节点,以及物理优化器如何以统计行数决定连接分布,串联Java分布式SQL引擎架构、SQL查询优化原理与gRPC分布式数据交换。
标签:jquick-sql架构原理、Join Reorder、Hash Join、Nested Loop Join、SQL查询优化原理、Java分布式SQL引擎架构
官网示例:
- FORMULAS 示例页:https://www.jquick.org/jquick-sql
- github 地址:https://github.com/paohaijiao/jquick-sql
前言
连接(Join)通常决定复杂查询的主要成本。JQuick-SQL 将连接优化分成两个层次:逻辑层的 JQuickJoinReorderRule 调整连接关系的组织方式;物理层的 JQuickPhysicalPlanGenerator 决定 Hash Join 或 Nested Loop Join,随后 JQuickPhysicalPlanOptimizer 依据统计信息选择连接分布方式。
这种分层避免把"表的连接顺序""连接算法""数据如何分发"混为同一个问题,是理解 jquick-sql架构原理 中 SQL查询优化原理的关键。
Join Reorder:逻辑层的重写
JQuickLogicalPlanOptimizer 默认注册 JQuickJoinReorderRule。它处理的对象是逻辑计划,而非已经执行的数据。逻辑层保留 Join 类型、条件、左右输入和别名等语义信息,重排序规则据此尝试改善计划结构;是否命中取决于具体计划与规则条件,不能承诺任意多表连接都必然被完全重排。
在这一阶段,计划尚未固定 Build Side、Hash 表实现或网络分区。这样后续规则仍可继续处理谓词下推、投影下推或子查询转 Join。
Hash Join与Nested Loop Join的选择
生成器访问 JQuickJoinNode 时,如果 Join 是 CROSS JOIN,或 isHashJoinApplicable(node) 判定为适合哈希连接,就创建 JQuickHashJoinPhysicalNode。它会从 join keys 或 condition 中提取等值键,并记录 BuildSide 与初始 SHUFFLE_HASH 分布。
java
if (node.getJoinType() == JQuickJoinType.CROSS || isHashJoinApplicable(node)) {
physicalNode = new JQuickHashJoinPhysicalNode(...);
} else {
physicalNode = new JQuickNestedLoopJoinPhysicalNode(...);
}
不满足 Hash Join 条件时,生成器使用 JQuickNestedLoopJoinPhysicalNode。因此,带非等值或无法提取等值键的条件不应被描述为必然走 Hash Join。
Build Side与分布策略
Hash Join 创建后,物理优化器会读取左右估算行数,选择 BROADCAST_HASH、LOCAL、PARTITIONED 或 SHUFFLE_HASH。当前源码阈值是实现细节:任一侧小于 1000 时选 Broadcast;双方小于 10000 时选 Local;任一侧大于 100000 时选 Partitioned;其他情况为 Shuffle Hash。
这些数值来自当前代码,不能写成对外配置项或通用经验法则。它们的意义是显示优化器确实利用统计规模做分布决策;需要跨 Worker 重分布时,计划可再引入 Exchange。
text
Logical Join
↓ Join Reorder等逻辑规则
Physical Generator
├─ 等值键 / CROSS → Hash Join
└─ 其他条件 → Nested Loop Join
↓
Physical Optimizer → Broadcast / Local / Partitioned / Shuffle
实操代码案例
项目 README 与 demo 支持标准连接语法。以下 SQL 是对真实能力范围的使用:
sql
SELECT e.dept, d.name
FROM emp e
INNER JOIN dept d ON e.dept = d.id
ON e.dept = d.id 是等值条件,因而属于生成器可识别 Hash Join 的典型形态。最终是否调整为广播、本地或 Shuffle,仍取决于物理计划统计信息。
常见问题
CROSS JOIN一定会高效吗?
不是。源码允许它进入 Hash Join 分支,但笛卡尔积本身可能产生大量行,仍需谨慎使用。
Nested Loop Join是否代表错误计划?
不是。它是项目真实物理节点,适用于不满足哈希连接条件的场景。
Join Reorder是否改变查询结果?
规则优化的前提是保持语义;外连接等语义敏感场景不能按内连接的直觉随意交换。
总结与拓展
JQuick-SQL 用 Join Reorder、Hash Join/Nested Loop Join 和统计驱动的分布选择组织连接执行。逻辑重写、算法选择与数据分布各自独立又顺序衔接,使连接优化更可解释、更易扩展。
Core Advantage
Join ordering, algorithm selection, and distribution choice stay separated and inspectable.
Applicable Scenarios
Equi-joins, non-equi joins, multi-table planning, and distributed join execution.