PostgreSQL函数功能剖析

401 阅读5分钟

函数功能基础知识介绍

  PostgreSQL同⼤多数数据库⼀样,可以把若⼲SQL语句组合在⼀起,然后将其作为⼀个单元来处 理,并且每次运⾏时可以输⼊不同的参数。这种机制在不同数据库中的名称不⼀样,有的叫存储过 程,有的叫⽤户⾃定义函数,而PostgreSQL 统⼀称之为:\color{red}{函数}

函数的基本结构

CREATE OR REPLACE FUNCTION func_name(arg1 arg1_datatype DEFAULT arg1_default)
RETURNS some type | set of some type | TABLE (..) AS
?
BODY of function
?
LANGUAGE language_of_function

函数参数的定义:

  • 命名参数:
big_elephant(ear_size numeric, skin_color text DEFAULT 'blue',
name text DEFAULT 'Dumbo')
--参数可以有默认值
  • 匿名参数
big_elephant(ear_size,skin_color,name)
  • 命名参数,采用带入参名的调用方式
big_elephant(name => 'Wooly', ear_size => 1.2)
--此时入参可以不考虑顺序

  笔者建议不需要采用花里胡哨的方式,按照函数入参顺序,方便阅读和后续的管理优化等操作。在包含PostgreSQL9.5以后的版本中,带参数名的调用方法是:name=>'Wooly',为保证兼容性,在PostgreSQL9.5以前的版本中调用的方法name:'Wooly'仍然可以在PostgreSQL9.5及以后版本使用,但尽量不要事后,因为以后的版本会删除!

PostgreSQL标记符

  • LANGUAGE(使⽤的编程语⾔)

  指明本函数使⽤的编程语⾔,当然该语⾔必须在当前函数所在的 database中已安装。执⾏SELECT lanname FROM pg_language; 即可查到已安装的语言列表。

  • VOLATILITY (结果的稳定性 )

  该标记符可以告诉查询规划器,当该函数执⾏完毕后,得到的结果是否可以缓存下来以供下次使 ⽤。它有以下⼏个可选值:

    1. IMMUTABLE (结果恒定不变 )

  任何情况下,只要调⽤该函数时使⽤相同的输⼊,就总会得到相同的输出。也就是说,该函数的 内部逻辑对外界完全⽆依赖。这类函数最典型的例⼦是数学计算函数。注意,定义函数索引时必须使 ⽤ IMMUTABLE 函数。     2. STABLE (结果相对稳定 )

  如果在同⼀个查询语句中多次调⽤该函数,则每次调⽤时只要使⽤相同的输⼊就总会得到相同的 输出。也就是说,该函数的内部逻辑在当前 SQL 的上下⽂环境内是有恒定输出的。

    3. VOLATILE (结果不稳定 )

  每次调⽤该函数得到的结果可能都不同,即便每次都使⽤相同的输⼊也是这样。那些更改数据的 函数和那些依赖系统时间这类环境设置的函数就属于 VOLATILE 类型。该项也是默认值。 请注意,VOLATILITY 标记符仅仅是给规划器提供了⼀个提⽰信息,规划器并不⼀定会按照此 设置来进⾏处理。如果函数被标记为 VOLATILE ,那么规划器每次遇到此函数都会重新解析并重新 执⾏⼀遍;如果被标记为别的类型,那么规划器也可能不会对其执⾏结果进⾏缓存,因为规划器可能 认为重新计算⼀遍反⽽会更快。

  • STRICT (严格模式)

  对于⼀个严格模式的函数来说,如果有任何输⼊为 NULL ,则规划器根本不会执⾏这个函数,直 接返回 NULL 。如果未显式指定为 STRICT 模式,则函数默认都是⾮严格模式的。写函数时,务必慎 ⽤ STRICT ,因为⽤了以后可能会导致规划器不使⽤索引。

  • COST (执⾏成本估计 )

  这是标记函数中计算操作密集程度的⼀个相对度量值。如果使⽤的是 SQL 或 PL/pgSQL 语⾔, 则该值为 100 ;如果使⽤ C 语⾔,则该值为 1 。该值会影响到规划器执⾏ WHERE ⼦句中的函数时 的优先级,也会影响到是否对此函数进⾏结果集缓存的可能性判定。此值越⼤,则规划器会认为执⾏ 该函数需要耗费的时间越多。

  • ROWS (返回结果集的⾏数估计 )

  仅当函数返回的是⼀个结果集时,此标记符才有⽤。该值是返回的结果集中记录数的⼀个估计 值。规划器会利⽤此数值来为此函数分析得出最佳的执⾏策略。

  • SECURITY DEFINER (安全控制符 )

  如果设置了安全控制符,则会以创建此函数的⽤户的权限执⾏此函数;如果未设置,则会以调⽤ 此函数的⽤户的权限执⾏此函数。如果某⽤户对某张表没有操作权限⽽⼜需要操作该表,那么就可以 让创建该表的⽤户提供⼀个带 SECURITY DEFINER 标识的函数来对此表进⾏操作。可以看出,当 需要进⾏表的访问权控制时,这个安全控制符还是很有⽤的。

  • PARALLEL (并⾏度 )

  该标记符是 PostgreSQL 9.6 新引⼊的。该标记表⽰允许规划器以并⾏模式运⾏。默认情况 下,函数会被设置为 PARALLEL UNSAFE ,这意味着任何调⽤该函数的语句都不会被分布到多个⼯ 作进程上去并发执⾏。详情请参考官⽅⼿册“并⾏安全性”相关内容。⽀持的选项如下:

    1. SAFE

  该选项表⽰允许该函数被并⾏执⾏。如果函数是 IMMUTABLE 类型的,或者函数不更新数据或者 不会修改事务状态或其他变量值,那么将其设为 SAFE ⼀般是没问题的。

    2.UNSAFE

  如果函数会修改⾮临时数据、访问序列号⽣成器或者事务状态,那么都应被设置为 UNSAFE 。 UNSAFE 的函数如果以并⾏模式执⾏可能会导致表数据被破坏或者其他系统状态被破坏,因此不允许 被并⾏执⾏。

    3.RESTRICTED

  对于使⽤临时表、预解析语句或者客户端连接状态的函数可以使⽤该选项。设置为 RESTRICTED 的语句不会被禁⽌并⾏执⾏,但是它只能运⾏在并⾏组中的领导组(lead)中,也就 是说该函数本⾝不会被并⾏执⾏,但它不会阻⽌调⽤它的 SQL 语句被并⾏执⾏。 本章的很多例⼦中都带有 PARALLEL 标记符,如果你的试验环境是 PostgreSQL 9.6 之前的版本, 请在执⾏例⼦时把 PARALLEL 标记去掉。