postgres union 是否保证调用有副作用的函数时的执行顺序?

2024-04-27

我正在使用 postgres 9.3 并尝试确保从 sql 语句调用时按顺序调用存储过程。 以下操作是否有效(确保首先调用 foo(),然后调用 bar())?

select null::void from (
    select 1 from foo()
    union select 1 from bar() ) _;

下面的也怎么样? [注意,因为它只是上述内容的一个稍微冗长的版本——我所追求的是一般 CTE 是否会按照“调用”的顺序、按照规范的顺序执行,还是未定义?]

with x as ( select foo() ),
y as ( select bar() )
select null::void from ( select 1 from x union select 1 from y );

除了正在进行的工作是否有效之外,是否有更惯用的方法来确保执行顺序(具有任意/不重要的返回值)?也许只是?

select null::void from ( select foo(), bar() ) _;

更新——解释原因:

我希望的是,如果我在 sql 中指定函数,优化器可以消除常见的子表达式(等),同时保持包含 DDL 的部分的顺序。例如,如果 foo、bar 是

create function foo() returns void language sql as $$
    with x as (select is_immutable())
    select is_volatile(x.is_immutable) from x
$$;
create function bar() returns void language sql as $$
    with x as (select is_immutable())
    select is_volatile_2(x.is_immutable) from x
$$;

优化器会将它们内联到 sql 中,并能够分解出对is_immutable(),同时仍保持不稳定的通话秩序。

妙语(如果你不想阅读克雷格耐心的解释)

优化器将内联“语言sql”过程,但它不会消除“公共子表达式”(或者至少不会以我希望的方式)。因此,尝试影响一条语句中的顺序或执行,而不是使用多个语句,是没有帮助的,至少对于我想要完成的任务来说是这样。下面列出了一个使用 CTE 的技巧,它可以工作——但正如@harmic 在评论中指出的那样,它可能在 postgres 的未来版本中不起作用,并且如果发生这种情况,可能会引入难以发现的偶发错误......我不相信控制执行顺序永远没有用,但克雷格的建议是确保在尝试之前有充分的理由,这当然是好的。


实际上,它们将按照给定的顺序执行,但不能保证。

如果得到保证,那么它将包含在文档或 SQL 标准中。我没有看到任何提及执行顺序的内容UNION在任一。

如果优化器有理由在另一个之前执行一个,那么它就可以自由地这样做。

为了确保执行顺序,请按所需顺序运行语句:

SELECT * FROM func1();
SELECT * FROM func2();

如果您想减少往返次数,请尽可能使用客户的配料设施,或使用DO block:

DO
$$
BEGIN
  PERFORM proc1();
  PERFORM proc2();
END;
$$;

如果需要返回值,请使用函数并RETURN QUERY or RETURN NEXT.

或者您可以强制使用 CTE 进行排序,因为在 PostgreSQL 中(不幸的是)CTE 充当优化栅栏,强制结果具体化 http://blog.2ndquadrant.com/postgresql-ctes-are-optimization-fences/。然而,据我所知 PostgreSQL 仍然不必按照 CTE 术语的编写顺序或引用顺序来执行它们;您得到的唯一保证是如果您这样做:

WITH f1 AS (SELECT * FROM function1())
SELECT * FROM function2()
UNION ALL
SELECT * FROM f1;

then function1必须首先执行并具体化。但这是 PostgreSQL 特有的缺陷;其他数据库引擎并非如此,不受标准保证,因此您不应该依赖它。

这并没有延伸到

WITH f1 AS (SELECT * FROM function1())
     f2 AS (SELECT * FROM function2())
SELECT * FROM f2
UNION ALL
SELECT * FROM f1;

...在这种情况下,PostgreSQL 可以按任一顺序执行独立的 CTE 项。

同样,对于连接,同样的原则适用。如果术语是独立的,那么系统可以选择以任何顺序运行它们,但通常不会。所以:

select null::void from (select 1 from foo() ) left join (select 1 from bar()) on true

可以评估并具体化bar()然后将其结果加入foo().

如果您想要有序执行,则不应依赖联合和联接等集合操作。使用单独的查询或过程代码。

是否有更惯用的方法来确保执行顺序(具有任意/不重要的返回值。

就在这里。

SELECT * FROM function1();
SELECT * FROM function2();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

postgres union 是否保证调用有副作用的函数时的执行顺序? 的相关文章

随机推荐

  • Typescript:映射联合类型时的类型级数学

    是否可以使用类型级数学来映射打字稿中的联合类型以生成作为第一个联合的函数的新联合 例如 我想使用现有的联合类型 type foo 768 1024 1280 为了产生这个并集 每个选项除以 16 type bar 48 64 80 如果工会
  • 编译资产时“堆栈级别太深”

    运行后brew upgrade 或者其他更新了我的 gems ruby 版本的东西 我的rake assets precompile任务不再有效 我收到此错误 rake aborted stack level too deep in Use
  • 梯度下降Matlab实现

    我已经浏览了堆栈溢出中的许多代码 并在同一行上编写了自己的代码 这段代码有一些问题我无法理解 我正在存储值 theta1 和 theta 2 以及用于分析目的的成本函数 x 和 Y 的数据可以从此下载页 它具有 dat 文件形式的 x 和
  • Rails 3 具有 12 小时格式的时间选择表单助手?

    Rails 3 有用户友好的 time select 吗 默认的 time select 表单助手为您提供小时 00 23 分钟 00 59 和可选的秒 00 59 对于我们这些非军事时间的人来说 0 23 小时的下拉列表非常令人沮丧 用户
  • System.Design 去哪儿了?

    我正在制作一个使用 ScintillaNet 的 C 项目 它显示 无法解析引用的程序集 ScintillaNet 因为它依赖于 System Design Version 4 0 0 0 Culture neutral PublicKey
  • 如何在reactjs中将可选元素作为 prop 传递给组件

    我试图找出正确的 反应 方式来传递一个可选的 prop 该 prop 是一个容器组件的 Element 该组件的处理方式与该组件的子组件不同 举一个简单的例子 我有一个面板组件 它渲染它的子组件 它还有一个可选的 title 道具 为了示例
  • 字母数字和空格的正则表达式

    不能包含除空格之外的任何特殊字符的文本的正则表达式是什么 Because Prajeesh https stackoverflow com users 112352 prajeesh只想匹配空格 s 不够 因为它匹配所有空白字符 包括换行符
  • 如何克隆 GitHub wiki?

    如何克隆 GitHub 存储库的 wiki 我知道它保存为单独的 Git 存储库 但我不记得路径了 我试过了 reponame wiki git and reponame git wiki 但两者都不正确 Append wiki git到存
  • 如何将带有动态内容的无序列表居中放置在 div 中?

    我正在尝试找出一种将 div 内的无序列表垂直居中的方法 我找到了很多方法来做到这一点 但是我的 ul 标签中的 li 标签中有 PHP 代码 可以从数据库获取文本 这会导致 li 标签中的文本长度发生变化 显着导致内部垂直筛选我的 div
  • SSIS Forloop:根据迭代次数为变量名称赋值

    我正在尝试使用 For 循环容器为最多 10 个不同的变量赋值 变量1 变量2 变量10 基于迭代次数 我需要循环根据一个变量迭代一定次数 该变量已根据查询的结果集分配了一个整数值 该部分工作得很好 我不知道如何告诉 for 循环使用哪个变
  • Android 中“屏幕尺寸”和“屏幕密度”之间的区别?

    我有几个问题 是什么屏幕尺寸 是什么屏幕密度 什么是不同之处之间屏幕尺寸 and 屏幕密度 Android 如何支持不同的密度和不同的屏幕尺寸 我已经读过官方文档 http developer android com training mu
  • 转换多索引时间序列的最有效方法

    我有一个由许多堆叠时间序列组成的 DataFrame 索引为 poolId Month 其中两者都是整数 月 是自 2000 年以来的月数 计算多个变量的一个月滞后版本的最佳方法是什么 现在 我做了类似的事情 cols to shift b
  • 按主题更改 ActionBar 的高度

    我想删除 ActionBar 下面的阴影 我知道我需要将高度更改为 0dp 但我想在主题中执行此操作 对于 Android 4 4 我使用
  • 您如何使用(描述的)技术来处理 .Net 中的 C 结构和指针?

    你如何使用这里描述的技术 https stackoverflow com questions 3235916 a way how to compile c library into net dll 3236027 3236027使用 Net
  • 在DOS中创建带有echo的文件而不插入回车符

    我想在 DOS 中的 CIFS 挂载上创建一个新文件 如果我做 echo hello gt foo txt hello 的末尾会有一个 CR 如何使用 echo 在 DOS cmd 中创建文件而不自动附加 CR 它导致 samba 和我的
  • 什么时候可以将函数绑定到另一个名称?

    在解释器中工作时 将函数绑定到名称通常很方便 例如 ghci gt let f 1 ghci gt f 1 2 这是别名f到函数 1 简单的 然而 这并不总是有效 我发现导致错误的一个例子是尝试使用别名nub来自Data List模块 例如
  • 在 IntelliJ 中创建新包

    我刚刚从使用 Eclipse 多年转向 IntelliJ 的美丽新世界 我正在努力解决那些拖慢我速度的小事情 当你知道如何去做时 最新的希望是显而易见的 我在源文件夹下创建一个新包 uk ac cam admin 我右键单击这个新包来创建另
  • 将仅限 HTTPS 的自定义域正确分配给 flex env

    将自定义域映射到 Google App Engine 项目的正确方法是什么 我已经添加了自定义域 设置了所有 DNS 记录等 并且它正在工作 但如何仅强制执行 HTTPS 就像生成的自定义域一样 从阅读周围many我看过的帖子secure
  • 当非特权用户运行 C/asm 程序时,会对 Linux 造成什么危害?

    我一直在考虑一种场景 让用户 可以是任何人 可能有恶意 提交在 Linux PC 我们称之为基准节点 上运行的代码 目标是为单线程例程创建一种自动化基准测试环境 假设一个网站向代理发布了一些代码 该代理将此代码交给基准节点 而基准节点仅与代
  • postgres union 是否保证调用有副作用的函数时的执行顺序?

    我正在使用 postgres 9 3 并尝试确保从 sql 语句调用时按顺序调用存储过程 以下操作是否有效 确保首先调用 foo 然后调用 bar select null void from select 1 from foo union