TiDB SQL Engine Team:纯手工打磨前沿的优化器和执行引擎|PingCAP 招聘季

“SQL at SCALE”(出自 PingCAP 官网)是咱们对 TiDB 的一个精简归纳,而咱们 TiDB SQL Engine Team 正是负责这 3 个单词中的 “SQL” 部分,其重要性可见一斑。SQL 在数据库中的大体处理流程能够简短归纳为查询优化和执行,这期间涉及到 SQL Parser、优化器、统计信息和执行引擎等模块,他们就是 TiDB SQL Engine Team 目前所负责的模块。接下来我会用简短的篇幅向你们介绍 SQL Engine 的背景知识,以及咱们在作的事情,面临的挑战等。html

关于查询优化

优化器是 SQL 引擎的大脑,负责查询优化。查询优化的主要工做归纳起来很简单:搜索可行的执行计划,从中挑一个最好的。但要作好这两件事倒是整个分布式数据库中最难的地方。ios

1979 年 Selinger 发布了 “Access Path Selection in a Relational Database Management System”,正式拉开了 Cost Based Optimization 的帷幕,这篇论文也被视为 CBO 优化器的圣经。在这以后陆续出现了 Starburst(1988 年),Volcano Optimizer Generator(1993 年)和 Cascades Framework(1995 年) 等,每一年数据库三大顶会中也能看到很多查询优化相关的论文,整个优化器领域可谓是蓬勃发展。但即便如此,优化器也仍然有不少问题未能获得很好的解决,好比:git

  1. Guy Lohman 2014 年在 “Is Query Optimization a “Solved” Problem?” 中详细讲述的 SQL 算子结果集估算的难题。简单来讲,要估算某个表须要扫多少行数据比较容易,可是要再估算更上层的 SQL 算子,好比 Join 或者 Join 以后再 Group By 的结果集有多大,这个就很难了。能够想象的是,估算偏差会随着层数的增长而被放大,这个放大有时候是数量级的。此外还会出现负负得正的状况:明明估算错了,可是执行计划倒是对的,纠正估算偏差后,执行计划反而不对了 🤷‍。
  2. Viktor Leis 等人在 2015 年的论文 How Good Are Query Optimizers, Really? 中讨论了优化器的另外一朵乌云:Join Order。若是枚举全部可行的 Join Order,光是考虑左深树,N 个表的 Join 就可能有 N! 种执行计划。目前你们广泛采用一种妥协的方案:当参与 Join 的表比较少时用动态规划来肯定 Join 的顺序,表比较多的时候用贪心或者遗传算法(PG 用的模拟退火)来作。可是采用什么样的动态规划和搜索算法也仍然处在热烈的研究中,而算子结果集的估算偏差又进一步让这个问题雪上加霜,难上加难。

做为一个从头至尾彻底本身手写的优化器,TiDB 优化器的发展历史也算精彩:一开始咱们是 Selinger 的 System R 模型,可是它的扩展性不是很好,搜索空间有限,维护成本也高,因而咱们调研后,决定开发 Cascades 模型的新优化器。具体请参考:十分钟成为Contributor 系列| 为Cascades Planner 添加优化规则揭秘TiDB 新优化器:Cascades Planner 原理解析。在开发 Cascades Planner 的同时,咱们还在作着另一件很是重要的事情,提高优化器的稳定性:github

  1. 优化器的稳定性很是重要。去年以前咱们常常遇到选错索引,或者干脆不选索引的问题。这个对业务的影响很是大,有时候一个慢查询可能拖垮整个集群,不少用户都吐槽过这个问题。后来调查研究后,咱们引入了 Skyline Pruning 的剪枝优化,极大地提高了优化器选择索引的稳定性。参考:Proposal: Support Skyline Pruning
  2. 优化器的稳定性很是重要。要稳定的作出好的执行计划,统计信息很是很是关键。之前咱们收集统计信息须要整个表都扫描一遍,扫的过程当中用蓄水池算法作抽样。小表这样作没啥问题,大表也这样作就不行了:一方面担忧对正在运行的业务形成影响,另外一方面这种方式也很低效。因而咱们结合 TiKV 的存储特色引入了 Fast Analyze,极大的提高了统计信息的搜集速度,也下降了对业务负载的影响。参考:PR/10214
  3. 优化器的稳定性很是重要。即便咱们作了各类优化,解了各类 Bug,仍然会出现执行计划不优的问题。有条件的用户还能够改一改 SQL,那没条件的呢?好比 SQL 是经过第三方工具自动拼接的怎么改?为了解决这些问题,咱们决定引入 SQL Plan Management,先实现了给 SQL 绑定执行计划的功能,使得不用更改业务也能抢救 SQL 的执行计划(Issue/8935);为了可以应对更多业务场景,更加细粒度的控制优化行为,咱们还丰富了 SQL Hint 集合(Issue/12304);为了让 SQL 执行计划不会变差,咱们为 SQL 肯定了 Plan 的 Baseline,而且再往前走一步,咱们作了 Baseline 的自动演进,使得执行计划不但不会变坏,并且只会变的愈来愈好。

重要的事情重复 3 遍:优化器的稳定性很是重要。算法

除了稳定性以外,还有性能问题:spring

  • 如何在尽可能短的时间内消耗尽可能少的硬件资源找到最佳执行计划?
  • 而目前 TiDB 正在 HTAP 之路上迈出坚实步伐,如何自动识别一条 SQL 是 AP 仍是 TP 查询?
  • 如何为 TP 查询选择合理的索引?
  • 又如何为 AP 查询作出一个高效的分布式执行计划?

能够预见,在这条道路上,优化器又将迎接新的困难和挑战,不断自我演进。数据库

关于查询执行

个人第一份工做从执行引擎开始,对它的感情异常深厚。执行引擎的目标是尽可能利用计算资源,正确且快速的完成执行计划所描述的计算任务。光有看起来很完美的执行计划,却没有高效的执行引擎,整个 SQL 引擎也是废的。express

执行引擎也是一个热门的研究领域。最经典的执行模型当属 1994 年 Goetz Graefe 发表的 Volcano 迭代器模型,至今仍被广大数据库使用。缘由很简单:接口抽象度高,扩展性好,实现起来简单。在数据量不大的 TP 请求中,这种模型足够用了。不事后来你们发现,随着数据量的上升,这玩意的执行性能不好:每完成一条数据的计算,要额外花费的不少 CPU 指令,计算效率很是低。因而有了后来的两大优化方向:Vectorization 和 Compilation,各自的表明分别为:2005 年 Marcin Zukowski 的 ”MonetDB/X100: Hyper-Pipelining Query Execution” 和 2011 年 Thomas Neumann 的 “Efficiently Compiling Efficient Query Plans for Modern Hardware”。架构

除了执行框架,如何利用 CPU 硬件特性优化各类执行算子也被普遍的讨论和研究。好比 2013 年的《Multi-Core, Main-Memory Joins: Sort vs. Hash Revisited》这篇论文详细的探讨和对比了 Hash Join 和 Merge Join 的实现和性能,2015 年的《Rethinking SIMD Vectorization for In-Memory Databases》这篇论文详细讨论了如何利用 SIMD 指令提高 SQL 算子性能。此外,底层软硬件技术的革新带来更多的优化机会,好比还有一系列论文来讨论如何适配 NUMA 架构,提高算子执行性能等。框架

做为一个从头至尾彻底本身手写的执行引擎,TiDB 执行引擎的发展也很是丰富多彩:一开始咱们使用的是传统 Volcano 迭代器模型,后来咱们和社区同窗在 TiDB 2.0 版本中将其优化成了向量化模型(Issue/5261),获得了巨大的性能提高:TPC-H 50G, TiDB 2.0 VS 1.0。以后咱们和社区同窗优化了聚合算子,重构了整个聚合函数的执行框架,执行性能又取得了飞跃的发展(Issue/6952)。再以后,咱们和社区同窗优化了表达式执行框架,使得表达式执行效率获得了 10 倍的性能提高,这期间 10x Performance Improvement for Expression Evaluation Made Possible by Vectorized Execution and the Community 这篇文章还占据了 Hacker News 的首页和 DZone Database 头版头条。

稳定性和易用性也很是重要。为了解决用户 OOM 的问题,咱们前后引入了内存追踪和记录的机制,后来干脆让算子落盘真正解决内存使用过多的问题,另外咱们也在优化排查问题的调查工具,方便在出问题时快速定位和 workaround。

如前文所说,目前 TiDB 正在 HTAP 之路上迈出坚实的步伐。执行引擎将在新的征程上肩负着新的使命。在分布式数据库中,广义上的执行引擎须要考虑更多的事情:任务如何调度?shuffle 如何优化?目前三套执行引擎(TiDB、TiKV、TiFlash)三套代码的维护成本如何下降?这些问题都等待着咱们去探索和解决,能够预见,在这条道路上,执行引擎又将迎接新的困难和挑战,不断自我演进。

期待你的加入

很开心,TiDB 的优化器和执行引擎是从零开始由咱们的小伙伴们纯手工打造的,咱们有很大的自由度来发挥本身的创造力;很紧张,上面这些列出来的种种问题咱们都会遇到;很荣幸,咱们可以和业界大牛、广大开源爱好者们一块儿来攻克这些难题;也颇有成就感,咱们能在广大 TiDB 用户的业务中看到这些改进为他们带来的价值。

咱们热爱开源,相信开源可以为咱们的产品带来巨大的收益,也愿意为开源奉献,很是期待一样热爱开源的你的加入。若是你:

  1. 热爱和相信开源,聪明且有激情;
  2. 勇于挑战上面那些难题,突破极限;
  3. 熟悉分布式系统、优化器和执行引擎的实现,熟悉 CPU 硬件特性;
  4. 有团队带领经验(加分项)。

那么咱们就加入咱们吧,一块儿向这些难题发起挑战,构建一个前沿、稳定的优化器和高效易用的执行引擎。

加入咱们吧!

咱们认为优秀的工程师或多或少有如下共同特质:

· A Quick Learner
· A- n Earnest Curiosity
· Faith in Open Source
· Self-driven
· Get Things Done

若是你符合以上特质,欢迎进入招聘页面查看目前开放的工做机会。

简历投递通道:hire@pingcap.com

实习生:公司的各项福利和学习资源对实习生全面开放,更重要的是实习生还未毕业就有机会接触工业级项目,并且实习期间表现优异者将有机会得到校招绿色通道特权。针对实习时间并不充裕的小伙伴,你能够先经过 Talent Plan 丰富基础知识(https://university.pingcap.co...),也能够经过参与 TiDB 开源社区得到更多实践机会!

伯乐推荐:若是你身边有符合以上要求的小伙伴,也能够找咱们聊一聊,推荐成功就有机会得到伯乐推荐奖励。伯乐推荐邮件格式:[伯乐推荐] 候选人姓名-职位名称-推荐人姓名-推荐人手机号。

延展阅读

是的,咱们在招人!PingCAP 2020 招聘季正式开启

TiDB Architecture Team:挑战数据库的本质难题

揭秘 PingCAP 年轻前沿的团队:用户生态

TiDB SQL Infra Team:一块儿打造从计算层到存储层的完美桥梁