Cra*_*ger 30

PL/PgSQL 和普通 SQL 函数都是更大工具集的一部分,应该在该上下文中查看。我倾向于从与复杂性和成本上升相匹配的能力的上升规模来考虑它,您应该使用最简单的工具来完成这项工作:

  • 尽可能使用视图
  • 在视图不合适的地方,使用 SQL 函数
  • 如果 SQL 函数不适合,请使用 PL/PgSQL。
  • 如果 PL/PgSQL 太有限或表达能力不够,请使用 PL/Perl、PL/Python、PL/V8、PL/Java 或任何您喜欢的
  • ...如果没有 PL 可以完成这项工作,请使用外部程序并可能LISTENNOTIFY它交谈。

通常,当您认为需要某个功能时,一个视图就足够了。即使它对SELECT整个视图来说非常昂贵,WHERE查询中引用视图的子句通常会下推到视图中,并可能导致非常不同的查询计划。通过将 SQL 函数转换为视图,我经常获得很大的性能改进。

您发现无法使用视图而应该考虑使用 SQL 函数的主要时间是:

  • 需要不能表示为简单WHERE子句的参数,例如WITH表达式中的参数
  • 您希望通过SECURITY DEFINER函数设置安全屏障,而security_barrierPostgreSQL 9.2 及更高版本中的视图不足以满足您的需求;
  • 您需要优化器未将参数下推到视图的子句中并希望更直接地控制它;或者
  • 有很多参数或者有很多重复的参数,因此将查询编写为视图是不切实际的。

对于大多数这些任务,一个普通的 SQL 函数可以正常工作,并且通常比 PL/PgSQL 更容易阅读。SQL 函数声明STABLEor IMMUTABLE(并且未声明STRICTor SECURITY DEFINER)也可以内联到调用语句中。当调用函数中的 WHERE 条件被优化器推送到 SQL 函数时,这消除了函数调用开销,有时还会带来巨大的性能优势。只要 SQL 函数足以完成任务,就使用它们。

SQL 函数无法完成这项工作的主要时间是当您需要大量逻辑时。If/then/else 操作无法表达为CASE语句、大量重复使用计算结果、从块中构建值、错误处理等。然后 PL/PgSQL 就派上用场了。当您不能使用 SQL 函数或它们不适合时,请选择 PL/PgSQL,例如:

  • 动态 SQL 和动态 DDL 通过EXECUTE语句
  • 当您想RAISE为日志或客户端显示错误/警告时
  • 当您需要异常处理时 - 您可以使用EXCEPTION块捕获和处理错误,而不是让整个事务因错误而终止
  • 不适合复杂的条件逻辑CASE ... WHEN非常好
  • 大量重复使用您无法适应的计算值WITH和 CTE
  • 建立动态记录
  • 生成结果集需要执行一个动作

对于通用表表达式 (CTE),尤其是可写 CTE,WITH RECURSIVE我发现我使用 PL/PgSQL 的次数比以前少了很多,因为 SQL 的表现力和功能要强得多。我现在更多地使用视图和普通 SQL 函数。值得记住的是,普通的 SQL 函数可以包含多个语句;最后一条语句是函数的结果。


kgr*_*ttn 8

plpgsql是一种成熟的过程语言,具有变量、循环结构等。SQL函数只是一个子查询。SQL 函数,如果已声明STABLE或未IMMUTABLE声明STRICT,通常可以内联到调用查询中,就像在每个引用上写出一样。