GaussDB技术解读高性能——计划缓存计划技术
数据库接收到SQL语句后通常要经过如下处理:词语法解析->优化重写->生成执行计划-> 执行,从开始解析到计划生成其实是一个比较耗时的过程,一个常用的思想就是将计划缓存下来,当执行到相似的SQL时,从而可以复用计划,跳过SQL语句生成执行计划的整个过程,在一般OLTP业务负载中,由于涉及到的数据量较少,同时借助索引技术能够大大加速数据的访问路径,因此查询的解析、重写、优化阶段占比会比价高,如果能够讲一些模板性质的语句计划缓存起来,每次设置不同的参数那么点查询的处理流程能够大大简化,提升查询时延和并发吞吐量。
计划缓存技术:当数据库收到一条 SQL 请求后,首先会通过查询即系模块对 SQL 文本做一次快速参数化处理,参数化处理的作用是把 SQL 文本中的常量参数替换成通配符 ?,例如 SELECT * FROM t1 WHERE c1 = 1 会被替换为 SELECT * FROM t1 WHERE c1 = ?。接着数据库会从计划缓存中查看有没有已经生成好的计划给这条参数化后的 SQL 使用。如果找到了可用的计划,数据库就会直接执行这个计划。如果没有找到可用的计划,数据库会重新为这条 SQL 生成执行计划,并把生成好的计划保存到计划缓存中以备后续的 SQL 使用。通常情况下从计划缓存中直接获取执行计划相比于重新生成执行计划,耗时通常会低至少一个数量级,因此使用计划缓存可以大大降低获取执行计划的时间,从而减少 SQL 的响应时间。
上图为对比走计划缓存、不走计划缓存的SQL执行过程,可以看到执行待计划缓存的查询语句可以规避掉大量的处理逻辑,在OLTP并发负载场景下提升效果镜像,首先,事务型负载单条查询执行时间本身就在毫秒级ms,查询解析、RBO/CBO优化等一些列过程也是毫秒级往往会超过查询本身的执行时间,另一方面,查询解析、RBO/CBO本身是消耗CPU计算资源的操作,这对事务型高并发、高吞吐的事务型复杂起来说非常明显的资源占用,如果能将这部分资源剩下、同时将查询解析的时延消减为0对整体性能是非常明显的提升。