AI SQL 审核系统是陆金所于2019下半年重点开发的一个智能化数据库优化工具,已经为陆金所节约了大量用于 SQL 审核的 DBA 和开发资源。陆金所数据架构团队负责人王英杰老师在2019年12月北京·ArchSummit全球架构师峰会上介绍了陆金所 AI SQL Review 系统演进话题,希望陆金所处理 SQL 审核工作经验给大家带来一些新的思路。
做过开发和 DBA 的同学应该都深有感触,SQL 的性能对核心系统的可用率至关重要。因为一条烂 SQL 拖慢整个系统甚至让系统宕机的案例比比皆是。所以在应用发版前,建立起一套行之有效的人工 SQL 审核流程,把 SQL 性能问题发现在上线前,是不少公司的主流做法。陆金所一直以来都非常重视应用发版前 SQL 的审核工作,为此还研发了一整套人工 SQL 审核系统。
人工 SQL 审核系统确实帮我们在上线前发现了大量 SQL 的性能问题,并进行了提前优化,避免了很多生产事故的发生。但人工 SQL 审核平台审核部分主要还是靠人工,所以非常依赖开发和 DBA 的人力资源,这样一来,为了有效运行人工 SQL 审核系统,将遭遇到开发和 DBA 的人力资源瓶颈。为什么这么说呢?
这里看一下人工 SQL 审核的流程,首先是代码提交,人工 SQL 审核平台会直接和代码库进行对接;
接下来是差异比较,人工 SQL 审核平台会读取出当前生产版本和待上线版本之间 SQL 代码的变动和执行计划差异,并自动生成比对报告;
之后是最消耗开发和 DBA 人力资源的人工审核阶段,由开发和 DBA 阅读比对报告并给出评估意见。评估意见被 SQL 审核系统作为标签数据永久保存;
最后是上线批准,在一个版本里每一笔 SQL 都经过审核并优化消除掉性能风险后,才允许上线提交到生产。
所以回顾整个人工 SQL 审核流程,会发现人工 SQL 审核系统具备以下特点:
这是陆金所研发的 SQL 审核平台功能界面,它会自动到代码库里去查找相同一个 SQL 标签在不同版本里的代码和执行计划变动情况,并生成报告给开发和 DBA 进行审核。开发和 DBA 可以点击通过并选择通过的意见,如果性能存在问题,也可以点击不通过并选择性能问题的分类,并输入优化意见。人工 SQL 审核平台会保存上面所有的评审数据。
这个平台自从2016年上线以来收集了陆金所每个版本下每笔 SQL 语句的代码、执行计划、评审和优化意见。所以基于这套人工审核平台我们收集了大量的标签数据。
可以看到图中是人工 SQL 审核流程第3个环节的详细展开,这同时也是一个对 SQL 审核打标签并进行标签收集的过程。整个流程基于 SQL 审核平台完成的事前准备开始,通过审核的直接具备上线条件,不通过的审核的将由 DBA 进行性能问题分类,并根据性能问题点设计对应的优化方案交由开发进行优化。优化完成后再次再次审核,一直到通过上线。其中无论是审核、分类和优化环节既是在做 SQL 的评审和优化,同时也是人工打标签的过程。而这个打标签的过程将消耗大量的开发和 DBA 人力资源。
在整个系统高速迭代的过程中,如果要确保人工 SQL 审核流程落地,开发和 DBA 的人力资源将成为巨大的瓶颈。所以,当时我们就在思考,能否有更好的解决方案。
基于此,研发团队开始了 AI SQL 审核系统的研发。
AI SQL 审核系统的研发条件有哪些呢?人工 SQL 审核平台上线三年后,积累下了大量真实的、和 SQL 审核相关的历史数据,包括 SQL 在每个应用版本的代码改动、生产环境执行计划变动、数据字典和统计信息,以及 DBA 的审核标签数据,和上线生产后的监控系统捕获的运行时效。所以可以考虑一下,是否可以基于此尝试使用算法来模拟 DBA 对 SQL 的审核。
那么如何才能使用历史数据加 AI 算法来模拟 DBA 对 SQL 的审核呢,这个场景具体是要解决一个什么问题呢?这个问题的核心是为了找到 SQL代码、执行计划、统计信息、绑定变量和执行效率之间的相关性。并通过相关性基于 SQL 代码、执行计划、统计信息、绑定变量来预测执行效率。如果可以准确预测出 SQL 的执行效率,就能准确的评估出 SQL 是否具备上线条件。
上图展示了 AI SQL 审核系统实现对 SQL 执行效率预测的实现方案。如图所示,AI SQL 审核系统主要有三大部分组成:输入为 SQL 审核平台以及其他自动化工具收集的 SQL 语句、执行计划、统计信息和绑定变量。目标是生产监控系统捕获的 SQL 的平均执行时间。我们希望通过算法可以找到这两者之间的关系。
模型则是包含四个部分,分别是:1)特征嵌入,2) 特征压缩降维,3)特征裁剪,4)预测
可以看到我们使用的预测模型是最为简单的线性预型,这么做的目的也是想让过拟合风险降到最低。下面对这四个个核心算法展开介绍。
特征嵌入的目标是对数据进行处理,把ai模型不可读的 text 格式转化为ai模型可以计算的数字格式。这里对 SQL 语句做了词频逆文档频处理。tf-idf 是一种业界常用的方法,从词频来突出 SQL 包含了哪些表,哪些字段。对于执行计划里的非数字信息,比如表的连接,索引的扫描方式,嵌套查询的关联方式等,我们做了素数编码。素数编码可以完整保留每个元素的全部信息,同时又抹去了元素之间的为位置关系。降低了位置关系对模型训练的干扰,方便机器学习。经过处理后把 SQL 语句、执行计划、统计信息和绑定变量转化成一个非常宽的矩阵。这样就完成了对输入数据的前期处理。
为了保证矩阵有解,并最大化降低过拟合风险。我们利用 VAEs 算法对稀疏的宽矩阵进行信息压缩降维,把上千个特征向量的矩阵压缩为53个特征向量的矩阵。在进行降维压缩的过程中,我们发现陆金所的 SQL 数据呈现明显的两极化,符合预期。
最后使用随机森林算法进行特征提取,从53个特征向量里保留30%信息增益最大的38个特征向量。从宏观 ROC 曲线可以看到保留30%的特征覆盖的面积最大、鲁棒性最强,因此我们只保留前30%信息。我们将这种方法称为粗粒度学习。及把回归问题先划分成一个多分类问题,先粗力度的学习特征与目标的相关性。这里,将我们基于 DBA 经验将 SQL 的执行时间划分为10个区间,具体区间如下:
基于之前生成的38个特征,我们做了一个线性回归来对 SQL 执行效率预测。预测的方案如下:
预测结果见蓝色曲线,可以看到预测结果存在一定的噪音和毛刺,但这些噪音可以接受的,因为总体趋势和生产环境的执行时长呈现高度一致性。因此基于这套模型,可以对 SQL 的执行效率进行一个大体上较为准确的预测。然后再基于预测结果,智能评估 SQL 是否具备上线条件。
最终将这个结果,作为 SQL 审核平台的第一道环节。如果 AI 审核通过即直接上线,人工不再审核。SQL 审核总量里80%的 SQL 都是符合性能预期的,这些 SQL 因为由 AI 直接审核后上线,所以也节省了80%的人工审核工作量。
如果对 SQL 的审核可以使用AI来智能评估,那对于性能不好的 SQL,是否也可以通过算法来模拟开发和 DBA 对 SQL 进行调优。即把 SQL 审核流程中分类和优化这两个步骤,也通过模型来模拟。基于此,我们开始了第二版本的研发。
如果把 AI 的学习过程当做是个搜索问题,那么之前使用的方法需要对问题的解做完全遍历,如左图(频率派)。简而言之,频率派需要大量的数据来支持模型做完全遍历搜索找到最优解。对于 SQL 优化问题 SQL对应的问题有很多种,如果让频率派学到一个最优解。那么每一种 SQL 问题都要对应一大批训练数据。其中的人力成本不可估计,这对于我们来说是不切实际的。
因此我们选择了贝叶斯派 (右图)。 贝叶斯派,基于先验可以对搜索空间做缩减,这样一能提高训练速度,二也解决了数据不足的问题。
这个版本只是一个“建议系统”,及对 SQL 提出可修改的建议。不同于 AI 预测 SQL 执行性能,对 SQL 给出优化建议,需要模型了解 SQL 的结构关系,比如多表之间的连接关系,单表字段与索引之间的关系等等。同时 SQL 性能优化系统对一个 SQL 往往会生成多个优化建议。对于大部分 n 到 1(n个输入 一个输出)的机器学习算法,并不能很好的解决问题。
这里我们提出了一种机器学习 + 搜索结合的方法,即基于贝叶斯的启发式搜索方法。启发式搜索分为三个部分:
这里主要介绍一下技术核心陆金所 SQL 解析器 LUParser:
LUParser 是在 AST 树基础上,进一步将列,表,视图等的关系解析成一个有向图。这种方式能够帮助机器更好的理解 SQL 里的关联关系,方便对 SQL 做系统优化。有向图的一个好处是能够保留比树更多的信息,可以通过有向图基于不同的需求,解析成不同的树。这里展示一个复杂的多层半连接嵌套 SQL 语句解析结果。可以看到有向图可以非常清晰的把包含三层嵌套子查询的 SQL 全部信息都展示出来。
下面是 LUPareser 的计算过程,主要有三部组成:
整个算法下来我们需要对 SQL 做三次遍历即可解析完成。
介绍完特征处理,下面会着重介绍一下启发式搜索:
只允许同一个状态至多能被使用一次。如果搜索发现没有可选状态或者候选状态为空时搜索终止。
下面介绍一下启发函数的训练方法,主要分为两个部分:
上线前对接代码库和发版平台,对审核不通过的 SQL,先给出一轮优化建议供开发和 DBA 参考。上线后对接监控平台,监控平台捕获慢查询后,调用 AI SQL 审核服务接口,自动给出优化建议。同时 AI 明确优化建议优于 CBO 的执行计划才会给出建议反馈。
我们的建议模型基于贝叶斯派模,虽然模型输出可控,但也会受限于 DBA 的经验。于是我们思考,能否开发一种激励算法,来鼓励模型去尝试对SQL做不同的优化。为此我们构思出了一种基于强化学习+对抗模型的 SQL 改写优化模型,希望模型通过不断的尝试改写 SQL 来学得如何去优化一条查询语句。该想法目前还处于研发阶段。
整个算法由三个神经网络模型组成。分别为:SQL 生成器,SQL 优化器,SQL 恶化器。
1. SQL 生成器:
2. 对抗模型:
3. 强化学习:
对抗模型优点:
理论上如果单使用强化学习,模型是可以学到如何优化 SQL 的。但是这里存在一个弊端,只用强化学习,会让模型接触的数据范围过窄,训练出来的模型泛化性过低。模型很容易学到只对某个 SQL 做优化的方法。
陆金所的 AI SQL 审核系统目前已经完成了对针对 Oracle 数据库 SQL 审核两个版本的研发,还会尝试开发支持 MySQL、Hive 和 Impala 等数据库 SQL 审核的功能。如果大家对陆金所 AI SQL 审核系统技术细节感兴趣,欢迎沟通。
领取专属 10元无门槛券
私享最新 技术干货