(相关资料图)

对于相同的查询语句而言,不同的查询计划带来的性能差异可能达到几个数量级的差异,其中较为显著的包括:是否命中索引、查询路径的规划、逻辑改写规则的应用、物理算子的选择等。主流现代数据库的计划生成主要依赖基于统计信息的代价估算,而在统计信息频繁跳变、数据倾斜、多表链接等复杂场景下,用户常常需要使用Plan Hint对查询计划进行固化。

Plan Hint是语句语法的一部分,当前openGauss提供的能力包括指定基表扫描路径和索引使用、Join的顺序及其物理算子、指定结果集行数、指定语句级生效的GUC参数等。但在实际的生产业务中,直接修改语句使得Plan Hint生效的成本极大,需要对用户业务升级并发新版本,导致问题响应时间达到小时级。

openGauss自3.1.0版本引入了SQLPatch功能,能够在避免直接修改业务语句,通过调用数据库提供的接口,对指定的查询语句模板进行hint调优,从而大幅提高查询计划性能问题的解决效率。

在创建SQLPatch时,用户需要首先获取目标语句的唯一编号(unique SQL ID),这样的好处时能够在很大程度上提高SQL Patch的命中率,因为唯一编号在生成时会对绑定的参数变量以及硬编码在语句条件中的常量参数进行归一化,从而忽视这些变量的不同。需要注意的是,语句唯一编号的生成过程需要使用到查询语句的语义信息,因此即使是相同的语句在不同的数据库之间也是不同的,而SQLPatch的生效范围也是数据库级别,需要用户在业务库中创建正确的SQLPatch才能够正确地影响计划。

SQLPatch会在被创建后即刻生效,并且会处理其对应的计划缓存使之失效并根据SQLPatch的内容重新生成计划,而在备机读的场景下,主机创建SQLPatch的语句需要在日志同步到备机并回放后才能再备机上生效,因此可能存在一定的时间窗。

正确地使用SQLPatch可以将单次业务计划调优的任务量从业务升级降级为单条运维语句,大大提升了运维效率,但不建议业务长期依赖SQLPatch,最好在业务例行升级时将调优语句固化到业务中,提升业务稳定性。

场景示例:使用SQL-PATCH对特定语句进行Hint调优

通过上面的案例,我们可以看到SQLPatch功能可以很容易地改变SQL语句的执行计划,并且代价和成本极低,这为openGauss的使用带来了一种更加便捷的方式。未来,我们还会在此基础上演进出更富有竞争力的产品特性,欢迎大家关注。

关键词: 查询语句 统计信息 语义信息