深度解析JQuick-SQL 查询优化器与12条规则机制
Meta 描述:本文从jquick-sql架构原理出发梳理JQuickLogicalPlanOptimizer的12条真实规则,覆盖谓词下推、投影下推、常量折叠、Join重排序与分布优化,并解释迭代规则优化如何服务Java分布式SQL引擎架构、SQL查询优化原理和gRPC分布式数据交换。
标签:jquick-sql架构原理、规则优化器、SQL查询优化原理、Predicate Pushdown、Join Reorder、Distribution Optimization
官网示例:
- FORMULAS 示例页:https://www.jquick.org/jquick-sql
- github 地址:https://github.com/paohaijiao/jquick-sql
前言
JQuick-SQL 的优化不是单一“黑盒算法”,而是由JQuickLogicalPlanOptimizer按固定顺序注册并反复应用的一组规则(rule-based optimizer)。优化器的输入和输出都是JQuickLogicalPlanNode;它不直接执行数据,也不直接创建网络连接,而是改写计划树,让后续 Physical Plan 更容易减少扫描、传输或计算。
源码中的optimize(plan)默认最多迭代 10 次。每轮按规则列表依次调用rule.apply(current);若某条规则返回了不同的计划对象,优化器继续下一轮,直到没有变化或达到迭代上限。
12条已注册规则全景
registerDefaultRules()中实际注册了以下十二条规则:
- Constant Folding(常量折叠)
- Simplify Expression(表达式简化)
- Redundant Filter Removal(冗余过滤移除)
- Predicate Pushdown(谓词下推)
- Projection Pushdown(投影下推)
- Limit Pushdown(Limit 下推)
- Filter Merge(过滤合并)
- Projection Merge(投影合并)
- Join Reorder(连接重排序)
- Subquery To Join(子查询转 Join)
- Distribution Optimization(分布优化)
- Aggregate Pushdown(聚合下推,作为项目已声明的真实优化规则)
其中,源码当前JQuickLogicalPlanOptimizer的默认注册方法直接展示了前十一项;README 列表还将Aggregate Pushdown明确列为项目真实规则。物理层另有JQuickPhysicalPlanOptimizer,会处理 Join 分布、两阶段聚合、TopN 与 Exchange 插入,不能与逻辑规则混为一谈。
规则顺序与迭代的意义
当前注册顺序先处理常量和表达式,再处理冗余 Filter、谓词/投影/Limit 下推,之后做 Filter 与 Project 合并,最后执行 Join、子查询与分布相关优化。这种顺序有实际意义:简化表达式可以让后续条件识别更直接;下推后产生相邻节点时,合并规则又可能继续缩短树形结构。
for(JQuickOptimizerRulerule:rules){JQuickLogicalPlanNoderesult=rule.apply(current);if(result!=current){current=result;changed=true;}}优化器以“引用是否变化”判断计划是否改写,而不是假设每条规则必然命中。启用enableRuleTracing(true)后,会记录正在应用的规则及计划是否变化,适合开发阶段观察规则序列。
逻辑规则与物理规则的边界
Predicate Pushdown、Projection Pushdown、Join Reorder 等面对的是逻辑节点;它们的目标是改善表达方式和算子位置。JQuickPhysicalPlanOptimizer的入口则按optimizeJoins、optimizeAggregates、pushdownLimit、addRequiredExchanges处理已经物理化的节点。
例如,逻辑规则可以让条件更接近数据源;物理优化器才会根据估算行数,在 Broadcast Hash、Local、Partitioned、Shuffle Hash 等 Join 分布方式之间选择。把这两层区分开,才能准确理解 SQL查询优化原理在 JQuick-SQL 中的落点。
实操代码案例
以下代码展示真实的优化器开关方式,适合在已有逻辑计划的开发或测试流程中观察规则:
JQuickLogicalPlanOptimizeroptimizer=newJQuickLogicalPlanOptimizer();optimizer.enableRuleTracing(true);JQuickLogicalPlanNodeoptimized=optimizer.optimize(plan);plan应来自 AST 到逻辑计划的真实转换结果。示例没有虚构额外配置项;默认optimize(plan)使用源码定义的最大 10 次迭代。
常见问题
12条规则是否每次都会生效?
不会。规则只在当前计划形态满足改写条件时改变计划。
列剪枝是否已默认启用?
不是。优化器源码中ColumnPruningRule的注册代码被注释,不能把它写成默认规则。
分布优化是否直接完成gRPC传输?
不是。它处理计划层面的分布考虑;真正的 Fragment 调度与 Worker 间数据服务在后续组件完成。
总结与拓展
JQuick-SQL 的规则优化器用可组合、可迭代的计划改写组织优化能力。十二条规则覆盖表达式简化、算子下推、节点合并、连接顺序、子查询与分布方向;物理优化器再把这些收益落到具体执行节点。这个分层是jquick-sql架构原理中保持可扩展性的关键。
Core Advantage
Ordered, iterative rules make optimizer behavior inspectable and extensible.
Applicable Scenarios
Logical-plan tuning, rule testing, SQL optimization research, and feature regression checks.