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
,而性能损失微不足道。
对 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
(
...
)
每个
结果查询由数万个多层嵌套的UNION ALL查询按照严格的约定顺序组成,像树的深度遍历,所以结果查询是几十亿行的数据集。
所以问题是:由于SQL不保证UNION ALL语句的顺序,外部查询应该包含ORDER BY子句,但服务器硬件无法在要求的时间内对billon行进行排序。
但是,联合查询的顺序是严格确定的,应该是:
有必要强制 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
,而性能损失微不足道。