Page 295 - 《软件学报》2026年第1期
P. 295

292                                                        软件学报  2026  年第  37  卷第  1  期


                  5   查询改写

                    查询改写是一类特殊的查询优化方法, 与前几种方法不同的是, 它的优化点并非是优化查询计划上的缺陷, 而
                 是查询语句结构上的缺陷. 由于一条查询有无穷多种等价的                    SQL  表述方式, 不同专家和应用程序写出的 SQL           各
                 不相同, 所以查询改写可以优化的问题非常广泛. 并且其中有许多问题传统优化器难以注意到, 比如查询优化器很
                 难通过某种固定的规则去分辨哪一层嵌套的子查询是冗余的, 或者哪一处的聚合其实是不必要的. 所以这些问题
                 只能通过查询在真正输入数据库之前的查询改写环节解决, 即查询改写算法对于智能查询优化算法的研究而言具
                 有不可替代的意义: 因为一旦查询语句通过了语法解析生成了对应的逻辑计划, 后续的查询优化过程会默认计划
                 中每一步的操作都是必要的, 从而很少进行语义等价的替换优化.
                    查询改写是基于规则进行的          [96] . 以广泛使用的  Apache Calcite 改写库为例, 它其中包含了    50  余条常见的改写
                 规则, 每一条规则都代表着一种对查询语句的等价变换, 但这些规则并不保证一定会带来正优化. 所以对于查询改
                 写方向的研究一方面在于如何决定要应用哪些规则, 以及用什么样的顺序应用这些规则; 另一方面在于创造新的
                 规则.
                  5.1   优化已有规则的应用策略
                    在优化已有规则的应用策略方面, LLM-R2            [97] 通过提示大语言模型来为查询选择适合应用的规则集合, 其提
                 示的核心原则有二: 一是它会用基于           QueryFormer [36] 的方法来判断已经进行过改写的查询语句有哪些是与当前待
                 改写的查询语句相似的; 二是与当前待改写的查询语句相似的查询语句改写效果如何, 然后让将这些信息传递给
                 大语言模型, 让其判断对于当前这条待改写的查询而言什么样的改写规则集合更适合它.
                    但是  LLM-R2  没有考虑到应用改写规则的顺序. 相比而言, LearnedRewrite         [98] 将查询改写过程建模为一个蒙特
                 卡洛树搜索的过程. 它将初始计划作为搜索树的根节点, 然后每一个节点的子节点都是从该节点出发可以通过应
                 用互不冲突的改写规则得到的新计划. 通过这种方式, 策略树逐步展开, 每个分支代表了一系列不同的改写规则应
                 用序列. 在每次迭代中, 蒙特卡洛树搜索会基于已探索节点的代价估计结果来决定下一步最有希望的探索方向.
                    从优化空间上来讲, LearnedRewrite 相比     LLM-R2  多考虑了可以按照不同顺序多次调用查询改写规则的情况
                 (反映为在蒙特卡洛树搜索中的不同分支), 在都使用同样的                  Calcite 查询改写规则库的基础上带来了更高的优化上
                 限; 不过从优化效果上来讲, LearnedRewrite 使用的蒙特卡洛树搜索方式中的剪枝策略依赖于代价估计的结果, 而
                 代价模型的准确度对于        LearnedRewrite 来说是一个较大的瓶颈, 在有些时候可能会因为次优的剪枝从而错失最佳
                 的查询改写方案, 而      LLM-R2  通过评估查询之间的相关性只需要给出相关或不相关的判断即可, 相对错误率较低.
                    所以在   LLM-R2  和  LearnedRewrite 的前车之鉴下, 有研究者就开始考虑如何可以同时借用大语言模型的理解
                 能力并且不丧失按照不同顺序多次调用查询改写规则的优化上限. 其中的代表工作                            R-Bot [99] 收集了数据库文档、
                 查询优化规则代码和论坛问答内容作为“重写证据”. 然后与                   LLM-R2  类似, 它会从这些“重写证据”中选择与要优
                 化的查询相关的“证据”帮助大语言模型选择要使用的规则. 同时它也考虑到了有一些规则是在另外一些前置规则
                 应用之后再应用才会有效果. 所以又与            LearnedRewrite 类似地, 它会采用迭代的方式逐步去改写一条查询, 这样就
                 可以避免选择了正确的规则集合, 但是应用顺序不正确的问题.
                  5.2   创造新规则
                    经过多年来专家经验的积累, 现有改写规则库中的查询改写规则已经比较完备, 所以很多运用机器学习方法
                 创造的新规则只适用于一些特定场景或特定结构的查询语句, 比如谓词之间有隐含的线性关系的查询                                  (SIA [100] ) 或
                 是  ORM  产生的查询   (WeTune [101] ) 等. 同时创造新规则的查询改写方法需要证明其创造的规则满足逻辑等价性,
                 这通常需要严格的数学推导证明或者在每次改写完成之后判断改写前后的逻辑等价性. 这个过程虽然一般由谓词
                 逻辑求解器完成, 但是由于求解的查询结构不同和求解成本的限制, 验证逻辑等价性依然是这类方法的瓶颈. 关于
                 验证查询逻辑等价性的算法也有许多, 不过与查询优化算法的关系比较疏远, 本文不再列举.
                    对于一些谓词之间存在隐含线性关系的查询, SIA               可以通过查询中谓词之间隐含的线性关系合成出新的谓词.
   290   291   292   293   294   295   296   297   298   299   300