Erw*_*ter 10 postgresql order-by union
根据标准 SQL UNION/UNION ALL不保证没有外部ORDER BY子句的任何特定排序顺序 - 就像 SQL 中几乎没有任何地方不保证排序顺序一样ORDER BY。
然而,Postgres 对 的普通情况使用“附加”步骤UNION ALL,因此第一个分支的结果(即使在其分区中未排序)总是出现在下一个分支之前,等等。Postgres 只是按照给定的顺序附加每个分支的结果。这与以下LIMIT条款特别相关:
SELECT 1 FROM tbl -- or any complex query
UNION ALL
SELECT 2
LIMIT 1
Run Code Online (Sandbox Code Playgroud)
显然这不适用于UNION(without ALL)。但除此之外,我从未见过 Postgres 无序返回,即上述查询中的“2”SELECT ,而第一个查询也会返回行。即使第一站的费用极其昂贵,也不会。
我过去曾对这种行为进行过查询。现在我遇到了一个说法, Postgres 可能会在这里返回无序的行,但没有实际证据证实。
当前的Postgres 手册对此事有这样的说法:
UNION有效地将 的结果附加query2到 的结果query1(尽管不能保证这是实际返回行的顺序)。此外,它还从结果中消除重复行,其方式与DISTINCT, except相同UNION ALL。
这还不清楚。引用的顺序是否适用于子句列表SELECT,或每个子句中的行,还是仅适用于返回的集合?另外,UNION ALL仅在第二句中提到,因此尚不清楚最重要的第一句是否应该适用于UNION ALL......
任何人都可以展示一个示例,其中行返回无序,破坏了UNION ALL子句的顺序?在任何版本的 Postgres 中。(即使最新版本是最有趣的。)
如果不是这样,是否有理由相信这可能会在未来版本中发生变化?
ORDER BY这不是当前的问题。问题是多个UNION ALL子句是否按给定序列返回行(beforeLIMIT可以启动并停止进一步的分支执行)。
ype*_*eᵀᴹ 15
最近在 pgsql-docs 邮件列表中有一个类似的问题,
澄清组合查询中的排序保证(或缺乏):
我试图了解组合查询(UNION/UNION ALL/...)的排序方面的保证(如果有的话)。从该消息1可以看出,UNION ALL 确实保留了操作数查询的顺序,而 UNION 则不然(大概 INTERSECT、INTERSECT ALL、EXCEPT 和 EXCEPT ALL 也不保留)。
文档[2]没有提到这一点,我建议添加一个注释来澄清这一点。
汤姆·莱恩(和其他人)回答说:
由于文档不提供任何保证。如果您想要有序输出,请使用 ORDER BY。
不,没有任何保证。只是 UNION ALL 今天以这种方式工作(保留子选择的顺序) - 我什至不确定这一点,它可能不会在所有情况下保留顺序,具有不同的索引或分区或并行计划等。无论如何,不能保证未来的行为不会因为规划器的改进而改变。
是的,那个。您今天可以获得 UNION ALL 的并行计划:
Run Code Online (Sandbox Code Playgroud)=# explain analyze select * from foo union all select * from foo; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------- Gather (cost=0.00..208552.05 rows=5120008 width=244) (actual time=0.652..390.135 rows=5120000 loops=1) Workers Planned: 2 Workers Launched: 2 -> Parallel Append (cost=0.00..208552.05 rows=2133336 width=244) (actual time=0.021..228.848 rows=1706667 loops=3) -> Parallel Seq Scan on foo (cost=0.00..98942.68 rows=1066668 width=244) (actual time=0.453..78.084 rows=853333 loops=3) -> Parallel Seq Scan on foo foo_1 (cost=0.00..98942.68 rows=1066668 width=244) (actual time=0.024..125.299 rows=1280000 loops=2) Planning Time: 0.094 ms Execution Time: 488.352 ms确实,在简单的非并行化情况下,我们将执行第一个查询,然后执行第二个查询,但 SQL 不保证这是真的,Postgres 也不保证。
| 归档时间: |
|
| 查看次数: |
7301 次 |
| 最近记录: |