[英]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
(
...
)
每個 <QUERY i-th> 都是相對輕量級的查詢,它產生大約 100K-1M 行並且可以在內存中排序而不會顯着影響性能。
結果查詢由數萬個多層嵌套的UNION ALL查詢按照嚴格的約定順序組成,像樹的深度遍歷,所以結果查詢是幾十億行的數據集。
所以問題是:由於 SQL 不保證 UNION ALL 語句的順序,外部查詢應該包含 ORDER BY 子句,但服務器硬件無法在要求的時間內對 billon 行進行排序。
但是,聯合查詢的順序是嚴格確定的,應該是:<QUERY 1-1-1>,<QUERY 1-1-2>等等,分層排序,所以實際上外部查詢的排序是多余的,因為數據集已按 sql 查詢結構排序。
有必要強制 Postgres 保留嵌套的 UNION ALL 語句的順序。 怎么做? 歡迎任何插件、擴展甚至骯臟的黑客。
請避免在答案和評論中提及類似 XY 的問題 - 問題是以研究方式按原樣制定的。 問題條件不能改變數據庫和數據集的結構。 謝謝。
有兩種查看方法:
最安全的替代方法是使用 SERIAL 或 BIGSERIAL 聲明一個 id 列,這將被排序和索引。 由於記錄已經排序,因此對查詢速度的影響微乎其微,您可以確保排序沒有錯誤。
如果順序不重要,並且您根本不修改數據,則可能會按照您輸入的順序獲取數據。 沒有保證。 訂單對您的申請有多重要?
試試這個——將查詢的結果分配到一個臨時表中。 這是一步一步的:
the_temp_table
類似於<QUERY 1-1-1>
的記錄類型create temporary table the_temp_table as <QUERY 1-1-1> limit 0;
the_temp_table
增加一個自增主鍵列extra_id
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
,而性能損失微不足道。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.