这部分的主要作用是当接收到 SQL 请求时,如果能够直接查询到其对应的 Plan cash,那么就将这个查询计划返回给 Executor,避免经过长时间的 SQL 硬解析。
如果对一个 SQL 而言,执行时间远大于解析时间,那么做 Plan cash 模块的作用并不大。在 OceanBase 数据库面对的高并发场景里面,比如双十一期间,下单的流量非常的大,而操作时间很短,此时解析时间过长会造成很大的影响,因此需要避免 SQL 的硬解析。
OceanBase 提出了一种叫 Fast-parser 的方式,跟原来的 Parser 没有太大区别,主要是会对一个 SQL 语句进行常量的替换,方便去做一些 match。这里通过一个例子来帮助理解 Fast-parser 和 Plan cache 的作用。
首先来看什么是 Plan cash,如下图所示,当执行了两条 SQL 之后,查询 OceanBase 中的缓存视图,发现其中没有出现第二次执行的 SQL,只出现了第一次执行的 SQL,并且缓存命中数(hit_count)增加了 1 次。
出现上述情况是因为在进行第二条 SQL 查询的时候,进行了文本替换,将第二条 SQL 替换成了select * from t where c1=?
这样的一条 Statement,而条 Statement 的查询计划已经缓存在数据库中了,所以会直接将查询计划交给 Executor 进行执行,记录中就不会生成第二条 SQL 对应的查询计划。
为了避免使用原来的 Yacc/Bison 实际上是一个状态机的实现,OceanBase Plan 使用了 Fase-parser, 即匹配 Plan cache 时不需要将整个 SQL 去转化成一个语法树,再进行一系列复杂的状态机转换解析,而是只需要识别转换这个 SQL 语句中需要替换的部分,这也是 OceanBase 的一个优化。