簡體   English   中英

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
(
  ...
)

每個 <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 列,這將被排序和索引。 由於記錄已經排序,因此對查詢速度的影響微乎其微,您可以確保排序沒有錯誤。

  • 如果順序不重要,並且您根本不修改數據可能會按照您輸入的順序獲取數據。 沒有保證。 訂單對您的申請有多重要?

試試這個——將查詢的結果分配到一個臨時表中。 這是一步一步的:

  • 創建一個臨時表 ex。 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM