实际上,它们将按照给定的顺序执行,但不能保证。
如果得到保证,那么它将包含在文档或 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();