Page 289 - 《软件学报》2026年第1期
P. 289
286 软件学报 2026 年第 37 卷第 1 期
上接近 1, 而传统优化器 PostgreSQL 在 TPC-DS 上的最大 Q-Error 高达 116 900, 暴露了传统方法在大规模复杂查
询中的不足. 然而, 在真实数据集 JOB-Light 和 STATS 中, 数据分布呈现高偏斜与强相关性, 模型性能分化也更加
明显. 比如 QueryFormer 在 STATS 上的 Q-Error 最大值仅为 132.1, 显著优于其他模型, 突显出其处理复杂数据的
鲁棒性; 但是轻量化模型如 ReJOIN 和 Plan-Cost 在真实数据集上表现相对较差, 因为其简单特征编码难以应对高
偏斜场景.
深入分析性能产生的差异的原因可以发现, 代价估计的精准度与特征编码密切相关, 尤其是对谓词的精细编
码和与传统数据库预测值的结合. 表现较优的 QueryFormer 和 Bao 都采用了精细的谓词编码或整合了传统数据库
的基数估计等统计信息, 这样的设计使得他们在面对高偏斜数据时能够通过多维度特征缓解单一预测的偏差. 但
是方法如 ReJOIN 的编码仅涵盖操作符、表名和简单谓词编码, 并未充分挖掘谓词逻辑或利用优化器的预测值,
导致其误差可能会在复杂查询中被放大.
2.4 基于排序学习的代价估计模型
对于大部分查询优化算法的目标而言, 代价模型的核心任务并不是追求精准地估计单个查询计划的代价值,
而是正确判断若干个候选计划之间的相对优劣. 因此, 很多情况下代价估计的数值本身并不是最重要的, 重要的是
候选计划间的排序关系, 本节将介绍基于排序学习的代价模型训练方法 [4,65−67] .
一般的代价模型的训练流程是: 先执行训练数据集中的查询, 然后从数据库的执行记录中收集每条查询对应
的查询计划和代价信息, 最后将查询计划中的特征编码作为回归预测模型的输入, 代价信息作为监督信号对模型
进行训练 [68] . 基于排序学习的代价模型对此流程的改进主要在两个方面.
(1) 划分训练批次的方式不同: 一般的代价模型训练的批次数据是通过打乱所有数据之后取 k 等份 (一般每份
的数据量为 2 的整数次方), 然后每份作为一个批次输入模型; 而基于排序学习的代价估计模型是按照产生查询计
划的语句对批次进行划分的. 也就是说一般的代价模型在一个批次里可能同时有 a 查询语句产生的第 i 个候选计
划和 b 查询语句产生的第 j 个候选计划, 但是在基于排序学习的模型的训练批次中 a 查询语句产生的候选计划只
会和 a 查询语句产生的其他候选计划在一个批次中. 这样划分训练批次更加有助于模型理解查询计划之间的相对
优劣关系.
(2) 使用的损失函数不同: 一般用于代价模型的损失函数是 MSE 等常见于回归问题建模的损失函数. 而用于
训练排序学习的代价估计模型所使用的损失函数不需要考虑每条数据本身的绝对误差, 而需要考虑数据之间相对
关系判断的误差. 这样的损失函数主要分为两类: 成对 (pairwise) 的和成列表 (listwise) 的 [69,70] . 成对的方法关注的
是两个样本间的相对顺序 (大于或小于), 其通常使用交叉熵来作为损失函数. 成列表的方法则考虑的是所有样本
间的整体排序, 其通常使用可以体现列表位序的损失函数. 以 COOOL [67] 中成列表的损失函数为例:
∑
( )
L list (θ) = − lnPr PL σ q ;θ ,
q∈Q
其中, θ 是当前代价模型的参数, Q 是数据集中所有的查询, σ q 是当前一条查询产生的若干查询计划代价值的真实
排序, Pr P 的定义如下:
L
( )
n ∏ exp s q
( q q ) j
q
Pr PL t > t > ... > t ;θ = ,
1 2 n n ∑
q
j=1 ( )
exp s m
m=j
q
q
其中, s 是模型参数为 θ 时对查询语句 q 的第 j 个计划的代价 t 的预测得分, n 是查询语句 q 产生的计划数量.
j j
基于排序学习的代价估计方法不直接预测精确的代价值, 而是专注于样本之间的相对优先级关系. 这种特点
使其在面对训练数据中的噪声和不确定性时, 表现出了更强的适应性, 同时也可以节省大量的计算和内存资源. 所
以基于排序学习的方法在处理大规模数据集或高维度特征时, 表现出了更高的效率和更好的性能.
2.5 与代价估计相关的其他工作
除了对输入的 (子) 查询计划进行评估的主线任务之外, 还有一些其他与代价估计相关的工作.

