带自定义函数的语句不下推
问题现象
SQL语句不下推。
原因分析
目前GaussDB(DWS)可以支持绝大多数常用函数的下推,不下推函数的场景主要出现在自定义函数属性定义错误的情况下。
不下推语句的执行方式没有利用分布式的优势,其在执行过程中,相当于把大量的数据和计算过程汇集到一个节点上去做,因此性能通常非常差。
分析过程
- 通过EXPLAIN VERBOSE打印语句执行计划。
上述执行计划中出现__REMOTE关键字,表示当前的语句为不下推执行。
- 不下推语句在pg_log中会打印不下推的原因,上述语句在CN的日志中会找到类似以下的日志。
处理方法
审视用户自定义函数的provolatile属性是否定义正确。如果定义不正确,要修改对应的属性,使它能够下推执行。
具体判断方法可以参考如下说明:
- 函数相关的所有属性都在pg_proc系统表中可以查到,与函数能否下推相关的两个属性是provolatile和proshippable:
- 如果函数的provolatile属性为i,则无论proshippable的值是否为t,则函数始终可以下推。
- 如果函数的provolatile属性为s或v,则仅当proshippable的值为t时,函数可以下推。
- provolatile的本质含义是描述函数的易变属性,取值为i/s/v。i代表IMMUTABLE,s代表STABLE,v代表VOLATILE。
- 如果一个函数对于同样的输入,一定有相同的输出,那么这类函数就是IMMUTABLE的。例如,绝大部分的字符串处理函数,这类函数始终可以下推。
- 如果一个函数的返回结果在一个SQL语句的调用过程中,结果是相同的,那么它就是STABLE的。例如,时间相关的处理函数,它的最终显示结果可能与具体的GUC参数相关(例如控制时间显示格式的参数),这类函数都是STABLE的,此类函数仅当其属性是SHIPPABLE的时候,才能下推。
- 如果一个函数的返回结果可能随着每一次的调用而返回不同的结果。例如,nextval、random这种函数,每次调用结果都是不可预期的,这类函数就是VOLATILE的,此类函数仅当其属性是SHIPPABLE的时候,才能下推。
- proshippable字段表示函数是否可以下推到DN上执行,默认值是false,取值范围为t/f/NULL。