Union-all postgresql select 保留顺序的子句

Union-all postgresql select clauses preserving order

对 RDBMS Postgresql 进行复杂的 SQL 查询,其中包含多个嵌套的 UNION ALL-like 嵌套查询,如下所示:

(
  (
     (<QUERY 1-1-1> UNION ALL <QUERY 1-1-2>) UNION ALL
     (<QUERY 1-1-3> UNION ALL <QUERY 1-1-4>) UNION ALL
     ...
  ) UNION ALL
  (
     (<QUERY 1-2-1> UNION ALL <QUERY 1-2-2>) UNION ALL
     (<QUERY 1-2-3> UNION ALL <QUERY 1-2-4>) UNION ALL
     ...
  ) UNION ALL
  ...
) UNION ALL
(
  (
     (<QUERY 2-1-1> UNION ALL <QUERY 2-1-2>) UNION ALL
     (<QUERY 2-1-3> UNION ALL <QUERY 2-1-4>) UNION ALL
     ...
  ) UNION ALL
  (
     (<QUERY 2-2-1> UNION ALL <QUERY 2-2-2>) UNION ALL
     (<QUERY 2-2-3> UNION ALL <QUERY 2-2-4>) UNION ALL
     ...
  ) UNION ALL
  ...
) UNION ALL
(
  ...
)

每个 都是相对轻量级的查询,它产生大约 100K-1M 行并且可以在内存中排序而不会显着影响性能。

结果查询由数万个多层嵌套的UNION ALL查询按照严格的约定顺序组成,像树的深度遍历,所以结果查询是几十亿行的数据集。

所以问题是:由于SQL不保证UNION ALL语句的顺序,外部查询应该包含ORDER BY子句,但服务器硬件无法在要求的时间内对billon行进行排序。

但是,联合查询的顺序是严格确定的,应该是:等等,分层排序,所以实际上是外层查询的排序是多余的,因为数据集 已经 按 sql 查询结构排序。

有必要强制 Postgres 保留嵌套 UNION ALL 语句的顺序。怎么做?欢迎使用任何插件、扩展甚至肮脏的黑客。

请避免在答案和评论中提及类似 XY 的问题 - 问题是以研究方式按原样制定的。问题条件不能改变数据库和数据集的结构。谢谢

有两种查看方式:

  • 最安全的替代方法是使用 SERIAL 或 BIGSERIAL 声明一个 id 列,这将被排序和索引。由于记录已经排序,因此对查询速度的影响微乎其微,您可以确保排序没有错误。

  • 如果顺序不重要,并且您根本不修改数据,它将可能以与您输入的顺序相同的顺序获取。没有保证。订单对您的申请有多重要?

试试这个 - 将查询结果分配到临时 table。 这是一步一步的:

  • 创建一个临时 table 例如。 the_temp_table 喜欢 <QUERY 1-1-1>
  • 的记录类型
create temporary table the_temp_table as <QUERY 1-1-1> limit 0;
  • 将 auto-increment 主键列 extra_id 添加到 the_temp_table
alter table the_temp_table add column extra_id serial primary key not null;
  • 然后运行你所有的查询按正确的顺序一个接一个
insert into the_temp_table <QUERY 1-1-1>; insert into the_temp_table <QUERY 1-1-2>;
insert into the_temp_table <QUERY 1-1-3>; insert into the_temp_table <QUERY 1-1-4>;

insert into the_temp_table <QUERY 1-2-1>; insert into the_temp_table <QUERY 1-2-2>;
insert into the_temp_table <QUERY 1-2-3>; insert into the_temp_table <QUERY 1-2-4>;

-- continue 
  • 终于
select <fields list w/o extra_id> from the_temp_table order by extra_id;

-- no sorting is taking place here

因此,您将以可控的方式有效地模拟 UNION ALL,而性能损失微不足道。