pg 创建函数选项介绍

pg 创建函数选项介绍

易变性

分类

IMMUTABLE(不可变的)

  • 函数不会修改数据库且对于给定的参数总是返回相同的值。
  • 不建议查找数据库表,因为数据库表数据会修改,可能导致函数结果不同
  • 如果参数为常量或无参,在生成执行计划时就会被替换为函数值。绑定变量情况下,有助于性能提升,因为执行计划中保存的是函数值(参数为常量或无参)。
  • 对于函数里面的查询都是基于查询开始时的快照,不会看到数据修改

STABLE(稳定的)

  • 函数不会修改数据库且对于给定的参数在一次表扫描中返回相同的结果,在不同的SQL语句中函数结果会变化
  • 可以依赖于数据库查找,参数变量等,因为一次SQL执行中中这些不会影响结果。
  • 函数作为约束条件时,优化器对于此分类函数会把相同参数的多次调用优化为一次调用,只在执行期间执行一次。绑定变量情况下,在每次bind的时候重新计算函数值。
  • 对于函数里面的查询都是基于查询开始时的快照,不会看到数据修改

VOLATILE(易变的,不稳定的)

  • 函数值在一次表扫描中可能改变。如:random(), currval()。
  • 优化器不会对这类函数的行为做任何假定,每次用到此函数都会重新计算函数值。
  • 索引扫描条件中不能使用volatile函数,不然不会走索引扫描路径。
  • 对于函数里面的每个查询都有一个新的快照,会看到数据修改

stable函数和immutable函数不能直接调用UPDATE这种修改数据库的SQL语句. 但是通过perform volatile function或者select volatile function还是会修改到数据, 因为PostgreSQL不会有更深层次的检查.

设置原则

分类的时候需要严格分类。
VOLATILE: 有任何写入,有任何副作用,需要看到外部命令所做的变更,或者调用了任何VOLATILE的函数
STABLE:有数据库查询,但没有写入,或者函数的结果依赖于配置参数(例如时区)
IMMUTABLE: 纯函数。

并行属性

分类

PARALLEL UNSAFE(默认)

函数所在SQL不能在并行下运行。

PARALLEL RESTRICTED

函数所在SQL能在并行模式中运行,但是此函数执行被限制在并行组的领导者中,即该函数不能并行执行。

PARALLEL SAFE

表示该函数对于在并行模式中运行是安全的并且不受限制。

设置原则

  • 如果函数修改任何数据库状态、会使用子事务之类的方式改变事务(即便是临时改变,例如建立一个EXCEPTION块来捕捉错误的 PL/pgSQL)、访问序列或者对设置(如setval)做出持久性的更改,它们就应该被标记为PARALLEL UNSAFE;比如:currval。

  • 如果它们访问临时表、客户端连接状态、游标、预备语句或者系统无法在并行模式中同步的本地后端状态(例如setseed只能在组领导者中执行,因为另一个进程所作的更改不会在领导者中被反映出来,再比如pg_backend_pid, random),它们应该被标为PARALLEL RESTRICTED。

  • 其他情况考虑改成PARALLEL SAFE。只要不访问修改数据库的,都可以设置为safe,比如:mod。

一个函数本来不支持并行,但是却标记为了PARALLEL SAFE,会导致异常,因此如果不能确定并行支持情况, 应标记为UNSAFE(默认值)

函数严格性

CALLED ON NULL INPUT(默认) 参数为空仍会调用函数
RETURNS NULL ON NULL INPUT 任意参数为空,函数不执行直接返回空值结果
STRICT 任意参数为空,函数不执行直接返回空值结果

在函数任意参数为空,结果为空时,设置STRICT

其他选项(可选):

COST execution_cost

指定函数的估计执行代价,若返回一个集合,这就是每个被返回行的代价,对 C 语言和内部函数会指定为 1 ,对其他语言的函数则会指定为 100。

ROWS result_rows

该函数返回的行数估,默认1000行

SET configuration_parameter { TO value | = value | FROM CURRENT }

设置函数执行时参数的值,只作用域该函数。FROM CURRENT 表示使用创建函数时的参数值。

SUPPORT support_function 一般用不到

给planner提供了解函数的支持函数,需要为c函数,

SECURITY INVOKER | SECURITY DEFINER:一般用不到, 安全相关

SECURITY INVOKER(默认) 用调用该函数的用户的权限来执行它
SECURITY DEFINER 用拥有该函数的用户的权限来执行该函数
https://blog.csdn.net/weixin_39540651/article/details/104993820

LEAKPROOF

暂不考虑,视图提供行级安全相关,不设置(不接收参数或者不从安全屏障视图得到任何参数的函数不必被标记为LEAKPROOF以便被下推,因为它们从来不会从该视图接收数据。)

TRANSFORM { FOR TYPE type_name } [, … ] 一般用不到

CREATE TRANSFORM定义一种新的转换。 CREATE OR REPLACE TRANSFORM将 创建一种新的转换或者替换现有的定义。

一种转换指定了两个函数:

  • 一个“from SQL”函数负责将类型从 SQL 环境转换到语言。 这个函数将在该语言编写的一个函数的参数上调用。
  • 一个“to SQL”函数负责将类型从语言转换到 SQL 环境。这 个函数将在该语言编写的一个函数的返回值上调用。

你可能感兴趣的:(数据库,postgresql,function,parallel,immutable,stable)