内核实战教程第四期 _ 带你走进数据库 SQL 引擎
SQL 引擎作为数据库系统的三大核心模块之一,有着承上启下的作用。SQL 引擎负责承接客户端输入的 SQL 请求,并根据负载场景将 SQL 语句经过其解析、优化、执行等模块的处理后,将结果返回至客户端。
这看似简单的运行过程却涉及 SQL 引擎各模块的作用和工作原理。9 月 1 日 19:30 内核实战教程第四期将会带你走进数据库 SQL 引擎,了解 SQL 引擎的各个知识点。同时,带你了解 OceanBase 在查询改写和查询优化方面的实践和经验。众所周知,查询改写模块是优化器的重点和难点,也是 SQL 性能调优工作者和 DBA 都需要掌握的基础知识,通过本期教程,你会学习大量的改写规则,掌握改写和优化的精髓,设计出更高效的 SQL。
此外,本期教程还有 OceanBase 技术专家带你在线解析 MiniOB select-meta 实现思路,手把手教你实战数据库内核。
本期能帮你解决什么问题?1、「查询改写」 模块如何改写 SQL,才能对内核而言是一条“好 SQL”?2、通过编写 SQL 语句可以提升执行性能,为什么还需要查询优化器来对 SQL 进行优化?
直播内容抢“鲜”知
查询改写
为什么要改写 SQL 呢?我们知道, 查询改写模块向来是查询优化器的重点和难点,因为 SQL 是一种描述性的语言,所以为了获取同一个查询结果,不同用户会写出不同的 SQL。查询改写的目的就是把 “用户的好 SQL” 转化为更加易于优化的 SQL。
而在查询改写的过程中,通常会面临两个挑战。第一个挑战是正确性,正确性其实是很重要的一项指标,如果改写的 SQL 不等价,意味着返回结果可能不正确。在 OceanBase 里,工作人员每次做改写规则时,必须确定其语义上是等价的,有时需要从关系代数的角度证明改写规则是正确的,或通过大量的测试场景来保证正确性。第二个挑战是完备性,也就是说设计的改写规则,必须足够通用,能够覆盖用户所有可能的写法。
查询改写对完整性体现在模式匹配方面,正确性体现在等价变化方面。除此之外查询改写还要注意有效性的判断。在 OceanBase 数据库中,所有的查询改写可以分为两类。一类是基于规则的改写,总是把 SQL 往好的方向改写。其主要特点是触发这类改写总能生成更好的执行计划,这类改写算法总是有效的。
第二类是基于代价的改写,其主要特点是某些场景下改写后能生成更好的执行计划,有些场景下则不能。是否可以触发这类改写,需要优化器评估改写前和改写后 SQL 计划的代价,并根据改写是否可以降低计划代价决定改写是否触发。
在实际执行过程中,OceanBase 的查询改写框架会按照预定义的顺序,不断迭代基于规则的改写和基于代价的改写,直到收敛。
目前 OceanBase 的改写模块实现了非常多的改写规则,既包含学术届和工业界常见的改写规则,也包含了优化器开发人员从业务的实际场景中提炼出的改写规则。例如,基于规则的常量折叠、SPJ 和非 SPJ 的视图合并、连接消除等,基于代价的 Or-expansion、Group by replacement、窗口函数改写等。
查询优化
OceanBase 的物理优化器主要包含计划枚举和代价计算两部分。计划枚举可以枚举包含 Deep Tree、Bushy Tree 在内的多种计划形状,并且包含了 DP、Linear 在内的两种枚举算法。代价计算则涉及到统计信息、选择率计算和中间结果估计,以及代价模型等多方面因素的影响。
计划枚举是一个有确定性的算法。如果有三种连接方式,就会出现六个执行计划。每个执行计划都会计算代价,最终选择代价最小的执行计划。
在星型查询下,如果连接表超过 25 张,在不考虑物理算子实现、不考虑基于代价的改写、不考虑分布式优化的情况下,其逻辑执行计划就已经到了 2 亿级别。因此如何高效的枚举执行计划是查询优化面临的一个重要挑战。
在 OceanBase 里,如果基表个数小于十张,会使用动态规划算法。首先,枚举所有一张表的执行计划;然后,枚举两张表的执行计划;接着,枚举三张表的执行计划,以此类推。如果超过十张基表,在开源版本会有启发式的算法,快速收敛执行计划。
当 OceanBase 在枚举执行计划时,除了要保留代价最小的执行计划,还要保留存在 interesting order 的计划。因为存在 interesting order 的计划的序可能会被后续的算子用于消除排序。
索引(a) 的执行时间是十秒;索引(b)的执行时间也是十秒;主表的执行计划时间是五秒。此时,由于主表代价是最小的,p1 是有序索引,故保留 p1 和 p3。当连接顺序生成完成后,优化器会依次分配其它的算子,例如 group by、窗口函数、 order by 等。在分配其它算子的过程中依然遵循保留代价最小的计划和存在 interesting order 的计划的原则,直到所有算子分配完成后讲代价最低的计划作为最终的执行计划。
更多详细内容,敬请关注 9 月 1 日 19:30 「从 0 到 1 数据库内核实战教程」官方课程。
附录:内核实战教程第一期 | 成为内核开发者的第一步:搭建研发环境内核实战教程第二期|带你揭开数据库存储结构的神秘面纱内核实战教程第三期|为什么索引可以让查询变快?课程回放
赶快扫描下方二维码进入「OceanBase 入门到实战」群关注课程动态,和更多小伙伴一起学习进步
为帮助大家更好地学习数据库知识,结交新的朋友未来 OceanBase Meetup 也会走到更多的城市中大家进群后修改自己的群昵称哦【格式:姓名-城市-职位】
评论