Page 267 - 《软件学报》2026年第3期
P. 267

1230                                                       软件学报  2026  年第  37  卷第  3  期


                 CPU  开销  (31.24%+3.9% = 35.14%) 花费在谓词表达式求值上, 并且这种虚函数调用, 需要在运行时动态查找函数
                 地址, 导致频繁的     L1  高速缓存未命中, 成为数据库性能的瓶颈.
                  3.1.2    JIT  编译的选择
                    本质上, JIT  编译方法是将原本的解释执行时间            t J (N) 替换为编译时间  t C  与优化后机器码执行时间      t E (N) 的总
                        N  代表查询处理的数据量. 编译过程中的优化使得生成的机器码更加高效, 并避免了频繁的函数调用开
                 和, 其中
                        t E (N) < t J (N) 始终成立. 但为了使  JIT               t C +t E (N) < t J (N), 即查询计划的解释执行
                 销, 因此                               编译具有优势, 需要满足
                 时间必须大于编译和执行优化后机器码的总开销.
                    是否满足上述条件, 主要取决于查询处理的数据量和查询复杂度. 对于每一条记录, 解释执行与编译执行的差
                 值都是   t J (i)−t E (i), 因此数据量的大小直接决定了   t J (N)−t E (N)  的差值. 当数据量较小时,  t J (N)−t E (N) < t C , 此时
                 JIT  编译方法反而会导致性能下降, 因此不适合使用             JIT  编译. 另一个影响因素是查询的复杂度. 如第           3.1.1  节中所
                 述, 在  TPC-H Q6  查询中, 谓词表达式求值的     CPU  开销占比为    35.14%, 而在一些  OLTP  类查询中, 谓词表达式求值
                 的  CPU  开销只有不到   10%, 此时  t J (N)−t E (N) 的差值会大幅缩小. 尽管查询复杂度降低, 编译的时间开销也会有所
                               t C  存在一个基础值, 该基础值主要为环境初始化与动态链接的时间开销. 因此, 在复杂度较低
                 减少, 但编译时间
                 的查询中, 由于    t J (N)−t E (N)  的差值大幅缩小和  t C  的固定开销, 导致  t C +t E (N) > t J (N), 此时  JIT  编译会导致性能
                 下降.
                    在编译准备模块中, 是否启用          JIT  编译需综合评估数据规模       (N) 与查询复杂度    (M). 其中, N  表示待处理的数

                 据量, M  为查询中谓词表达式的数量. 二者的乘积反映了查询的总计算开销: 数据量越大、谓词表达式越多, 解释
                 执行的函数调用开销也越大, JIT        编译的效果越显著. 为了避免在小数据量场景或低查询复杂度场景下                       JIT  编译开
                                                                              N×M, 并与预设阈值      K  比较, 仅当
                 销大于性能收益, 导致性能下降的问题, MySQLJ 通过优化器统计信息动态计算
                 满足  N×M > K  时触发  JIT  编译. 阈值  K  的设定基于编译开销与典型查询解释执行成本的权衡, 具体值通过实验校
                 准  (见第  4.4  节).
                  3.1.3    JIT  实例初始化
                    JIT  实例的初始化过程主要包括设置执行会话、目标机器、数据布局和编译过程. 首先, 系统创建了执行控
                 制对象, 并基于此创建了        ExecutionSession, 负责管理  JIT  编译的整个生命周期, 包括内存管理和机器执行的管
                 理. 接着, 系统构建了目标机器, 目标机器是执行编译后代码的核心组件. 成功创建目标机器后, 系统会获取平台
                 的数据布局    (DataLayout), 该布局定义了数据在内存中的存储和访问方式. 在获取数据布局后, 系统创建了一个
                 工具来管理动态调用, 确保在代码执行时所有的调用都能正确处理. 接下来, 编译过程被分为几个层次: ObjectLayer
                 负责管理生成的对象文件, CompileLayer 负责将中间代码编译成目标机器码, OptimizeLayer 对代码进行优化, 以
                 提升执行效率. 最后, 系统通过创建 MainJD 动态库并将其与当前进程结合, 确保编译出的代码可以被动态加载
                 并执行.
                  3.2   表达式筛选模块
                    在可插拔引擎架构的数据库系统中, 服务层与存储引擎层之间的频繁数据交互可能导致大量冗余数据传输,
                 从而显著影响查询效率. 传统优化方案如索引条件下推                 (index condition pushdown, ICP) 通过将索引相关条件下推  [23]
                 至存储引擎层, 在数据访问阶段提前过滤记录, 以减少服务层与存储引擎之间的数据传输开销. 然而, ICP                              存在明
                 显局限性: (1) 仅支持索引条件且无法处理子查询; (2) 当索引条件选择率较高时过滤效果有限; (3) 难以适配存算
                 分离架构   (如云存储场景), 因存储层与计算层分离时需额外考虑网络传输与数据转换成本.
                    为了解决上述问题, 本文提出一种全量谓词条件下推机制. 与                   ICP  仅下推索引条件不同, 该机制通过动态代码
                 生成技术, 将查询中低选择率的谓词条件              (无论是否涉及索引) 编译为机器码并下推至存储引擎层直接执行. 其
                 实现方式借鉴了      ICP  的代码下推思想, 但进行了显著改进以突破其限制: 该机制不再依赖索引, 支持任意类型条件
                 的下推, 包括非索引字段和复杂表达式; 通过预编译机器码减少存储层与计算层之间的原始数据传输, 特别适用于
                 网络带宽受限的云环境; 并基于选择率动态判定下推条件, 避免高选择率谓词条件引入额外开销. 具体来说, 在
   262   263   264   265   266   267   268   269   270   271   272