介绍
如标题所示,这是一篇介绍in常量查询的源码解读文章,但又不限于in常量查询,因为其中涉及的很多设计与优化对于大多数查询都是普适的。 一如往常一样,我们首先会过一遍整体的执行流程,梳理一个大致的框架。紧接着,同时也是更重要的,我们会通过一系列在真实场景中遇到的问题(说白了就是性能优化),来对各种细节处理进行增强。
温馨提醒:建议有条件有兴趣的同学可以对照着本篇文章边调试(我基本上把重要的断点位置都截了图)边学习边思考,这样印象和理解应该会更加深刻。
希望大家在读完之后,可以尝试着回答以下一些问题来进行某种测验:
- 什么是分片裁剪?为什么要进行分片裁剪?
- 为什么要对物理SQL中值进行裁剪?
- 什么是plan cache?为什么需要?
- 为什么需要post planner ?
- XPlan是什么?为什么Xplan比物理SQL更优?
- 为什么要有一个ToDrdsRelVisitor?
- 什么是全局二级索引?如何利用?
- 以及其他散落于文章中或者阅读时的问题
从大致的流程说起
注:详细的执行流程请参考文章,PolarDB-X 源码解读(四):SQL 的一生 - 知乎,我们这里只介绍其中几个比较重要的环节。 我们拿一个非常简单的场景来看一下吧,一个简单的表如下,create table t(c1 int, c2 int, c3 int) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 2,一条最简单的SQL如下:select c3 from t where c1 in (1,2)。挑了五个阶段进行了并不太详尽的说明,如果你感觉比较抽象时,也可以动手调试一下,一些概念应该就会更加清晰了。
阶段一
我们需要将SQL文本解析为语法树,如果不合法,则报错,关键断点如下图,其中sql为输入的查询语句,statement为经过解析后的语法树。
需要注意的是,在这个地方,我们是只进行语法解析,而不进行语义解析。什么意思呢,比如你现在输入的SQL为select c1 from tt,此时虽然我们没有tt这张表,但是断点处还是会正常解析出一个SQLSelectStatement,有兴趣的同学可以打个断点试一下。
阶段二
如上分析,我们现在要进行语义的校验了,比如我怎么知道这张表存不存在