# 38.11.函数优化信息
默认情况下,函数只是一个“黑匣子”,数据库系统对其行为知之甚少。然而,这意味着使用该函数的查询执行效率可能会比执行效率低得多。可以提供帮助计划人员优化函数调用的其他知识。
中提供的声明性注释可以提供一些基本事实创建函数
命令其中最重要的是函数的波动性类别(不变的
,稳定的
或不稳定的
); 在定义函数时,应该始终小心地正确指定这一点。平行安全属性(平行不安全
,并行限制
或平行保险箱
)如果希望在并行查询中使用该函数,则还必须指定。指定函数的估计执行成本和/或集合返回函数估计返回的行数也很有用。然而,指定这两个事实的声明性方式只允许指定一个常数值,这通常是不够的。
也可以附加一个计划者支持功能一个SQL可调用函数(称为目标函数),从而提供有关过于复杂而无法以声明方式表示的目标函数的知识。Planner支持函数必须用C语言编写(尽管它们的目标函数可能不是),因此这是一个相对较少人会使用的高级功能。
planner支持函数必须具有SQL签名
supportfn(internal) returns internal
通过指定支持
子句创建目标函数时。
有关planner支持函数的API的详细信息,请参见src/include/nodes/supportnodes。H
在PostgreSQL源代码中。在这里,我们只提供planner支持功能的概述。对支持函数的可能请求集是可扩展的,因此在未来的版本中可能会有更多的事情。
在规划过程中,可以根据特定于函数的属性简化某些函数调用。例如int4mul(n,1)
可以简化为n
。这种类型的转换可以由计划支持功能执行,方法是让它实现支持请求简化
请求类型。将为查询解析树中找到的目标函数的每个实例调用支持函数。如果它发现特定的调用可以简化为其他形式,则可以构建并返回表示该表达式的解析树。这也将根据函数自动为操作员工作——在刚才给出的示例中,n*1
也将简化为n
(但请注意,这只是一个例子;这个特定的优化实际上不是由标准PostgreSQL执行的。)我们不能保证PostgreSQL永远不会在支持函数可以简化的情况下调用目标函数。确保简化表达式与目标函数的实际执行之间严格等价。
对于返回的目标函数布尔值
,这通常有助于估计将由哪里
子句使用该函数。这可以通过实现支持请求选择性
请求类型。
如果目标函数的运行时间高度依赖于它的输入,那么为它提供一个非恒定的成本估计可能是有用的。这可以通过实现支持请求成本
请求类型。
对于返回集合的目标函数,为将返回的行数提供非常量估计通常很有用。这可以通过实现SupportRequestRows
请求类型。
对于返回的目标函数布尔值
,可以转换出现在中的函数调用哪里
转换为一个或多个可索引运算符子句。转换后的子句可能完全等同于函数的条件,也可能稍微弱一些(也就是说,它们可能接受函数条件不接受的某些值)。在后一种情况下,指数条件被称为有损; 它仍然可以用来扫描索引,但必须对索引返回的每一行执行函数调用,以查看它是否真的通过了哪里
不管状况如何。为了创造这样的条件,支持职能部门必须实施SupportRequestIndexCondition
请求类型。