0 前言
在海山数据库(He3DB)+AI(三)中,介绍了四种旋钮调优方法:基于启发式,基于贝叶斯,基于深度学习和基于强化学习。本文介绍一种基于强化学习的旋钮调优方法:QTune: A Query-Aware Database Tuning System with Deep Reinforcement Learning。
1 QTuner框架
数据库旋钮调优问题是一个NP-hard问题,现有的解决方法中仍存在一些不足:
- DBA无法在不同的环境中对大量的数据库实例进行调优;
- 传统的机器学习方法依赖训练数据,而高质量的数据集难以获取;
- 大多数方法只支持粗粒度调优,如负载层面的调优,无法提供细粒度的调优,如query层面的调优。
为了解决以上不足,本文提出了基于强化学习的调优框架QTuner。QTuner首先将SQL语句进行特征向量化,然后将特征向量输入到训练好的模型中获得合适的旋钮配置。该深度模型使用了强化学习中的actor-critic网络,基于查询向量和数据库状态进行调优,能够在训练样本不足的情况下获得较好的效果。
QTuner中提供了三种不同粒度的调优:
- Query-level:在该调优方法下,对于每个query,首先调整数据库的旋钮,然后执行查询,该方法可以优化延迟,但可能无法实现高吞吐量。
- Workload-level:该调优方法对整个工作负载的数据库旋钮进行调优,这种方法不能优化查询延迟,因为不同的query可能需要使用不同的最佳旋钮值,然而,这种方法可以实现高吞吐量,因为不同的query可以在设置新调整的旋钮后并行处理。
- Cluster-level:在该调优方法下,将query分成不同的组,为每个组进行旋钮调优,同一组中使用相同的旋钮配置,并执行并行查询,该方法可以同时优化延迟和吞吐量。
三种不同粒度的调优流程如下图所示:
2 query特征化
在特征化的过程中,需要考虑以下问题:1)如何来捕获query的信息,如query中涉及多少表?2)如何捕获执行query的代价?3)如何对向量进行编码使得其维度一致?
2.1 特征提取
本节主要回答第一和第二个问题,即如何捕获query和代价信息。
(1)Query信息
将一条Query语句进行分解,一般包括以下几个部分:query类型(如insert,delete和update等),涉及的表,属性,操作(如selection,join和groupby)。在以上部分中,哪些特征是重要的呢?首先,query类型是重要的,不同的类型具有不同的代价。其次,涉及的表也是重要的,表的数据量和结构会显著影响数据库的性能。而属性和操作可以忽略,原因有三:一是代价信息中会捕获操作信息,不需要对该信息进行重复编码;二是操作信息太过于具体,可能会导致泛化性能降低;三是属性和操作信息更新过于频繁,每次更新都需要对模型进行重新设计。
(2)代价信息
代价信息捕获处理这条query时的执行代价,出于实际情况,使用优化器的成本估计来代替实际的执行成本。
2.2 编码方法
本节回答向量化的第三个问题,如何编码使其维度一致。
对于query信息,设计一个长度为 4 + ∣ T ∣ 4+|T| 4+∣T∣的向量,“4”对query类型(insert, select, update, delete)进行one-hot方式的编码,"T"代表数据库中的表,同样使用one-hot的方式进行编码。
对于代价信息,设计一个长度为 M M M的向量, M M M代表数据库中操作的个数(如postgre数据库中有38个操作)。优化器生成查询计划后,每个操作计算其在计划树中的代价和,最后通过减去均值和除以标准差进行归一化。
将query向量和代价向量拼接在一起,就得到了最后的特征向量。如下图为一个将query进行特征向量化的过程。
以上是对一条query进行特征向量化的过程,在工作负载调优时,涉及多条query,假设其编码后的特征为 v 1 , v 2 , . . . v m v_1,v_2,...v_m v1