openGauss-预编译慢问题

发布时间 2023-12-12 14:30:50作者: y_dou

背景:
使用opengauss3.0.3,JDBC使用占位符,PreparedStatement的方法测试,因为是压测和业务场景特殊,每次使用的参数都一致。

现象:
1、不传参的方法,将where条件变量写死,执行时间很快
2、修改enable_pbe_optimization=off,发现执行5次之后,依然慢

分析:
查看where条件带值的SQL执行计划,和使用prepare execute的执行计划发现,后者会使用不同的索引,并且走nestloop,导致开销异常大

opengauss对于这个参数的解释为:

enable_pbe_optimization:设置优化器是否对以PBE(Parse Bind Execute)形式执行的语句进行查询计划的优化。
取值范围:布尔型。
•on表示优化器将优化PBE语句的查询计划。
•off表示不使用优化。
默认值:on

实测参数打开后,会选择错误执行计划。

但是关闭此参数后,同一会话执行5次参数相同,相同的SQL后,第6次又选到了错误的执行计划

plan_cache_mode:标识在prepare语句中,选择生成执行计划的策略。
取值范围:枚举类型
•auto表示按照默认的方式选择custom plan或者generic plan。
•force_generic_plan表示强制走generic plan。
•force_custom_plan表示强制走custom plan。
默认值:auto

对于这种场景,只能修改plan_cache_mode为force_custom_plan。

custom plan是指对于preapre语句,在执行execute的时候,把execute语句中的参数嵌套到语句之后生成的计划。custom plan会根据execute语句中具体的参数生成计划,这种方案的优点是每次都按照具体的参数生成优选计划,执行性能比较好;缺点是每次执行前都需要重新生成计划,存在大量的重复的优化器开销。
generic plan是指对于preapre语句生成计划,该计划策略会在执行execute语句的时候把参数bind到plan中,然后执行计划。这种方案的优点是每次执行可以省去重复的优化器开销;缺点是当bind参数字段上数据存在倾斜时该计划可能不是最优的,部分bind参数场景下执行性能较差。