假設某些數據庫(PostgreSQL)中有N
表。每個表Ti
包含字段(time, label)
,其中time
是某個數字(例如長timestamp
)。 label
是一些文字。優化複雜查詢(使用分頁)
有N
條件。每個條件Ci
適用於特定表Ti
。每個條件可能很複雜(使用自己的子查詢,也可以加入)。
我需要從條件中收集所有表格T
的記錄並獲得排序結果的頁面。該任務由SQL
和UNION ALL
解決。下面的僞說明了在抓取了一些網頁:
(SELECT time, label FROM T1 WHERE C1
UNION ALL
SELECT time, label FROM T2 WHERE C2
UNION ALL
...
SELECT time, label FROM Tn WHERE Cn)
ORDER BY time LIMIT = x OFFSET = y
DISTINCT
如果條件C
是複雜,表中包含大量的記錄,則上面的查詢是非常巨大而緩慢的。 我想將這個複雜的查詢拆分爲子查詢,其中每個子查詢Qi
應用於相應的表Ti
。在這種情況下,每個子查詢的執行速度會更快,但與聯合結果相關聯的問題會對分頁進行排序。
爲此,我打算使用akka-streams
和slick-streaming
。下面的僞代碼示出了取出一些頁兩個表:
val streamT1 = Source.fromPublisher(db.stream(Q1.sortBy(time)))
val streamT2 = Source.fromPublisher(db.stream(Q2.sortBy(time)))
val pageContent = streamT1.mergeSorted(streamT2)
.grouped(pageSize).drop(pageNumber)
.runWith(Sink.headOption)
下面的示例示出了用於兩個表分頁:
val srcT1 = Source(
(0, "A_a"),
(1, "A_b"),
(2, "A_c"),
(5, "A_d"),
(7, "A_e"),
(8, "A_f"),
(9, "A_g"),
(10, "A_h"),
(11, "A_i"),
(15, "A_j"),
(16, "A_k"),
(17, "A_l"),
(20, "A_m"),
...
)
val srcT2 = Source(
(3, "B_d"),
(12, "B_e"),
(18, "B_f"),
...
)
時間表上述集合的曲線圖是在以下內容:
0 1 2 5 7 8 9 10 11 15 16 17 20
| | | | | | | | | | | | |
A_a---A_b---A_c---------------A_d---------A_e---A_f---A_g---A_h---A_i---------------------A_j---A_k---A_l---------------A_m--->
3 12 18
| | |
------------------B_d---------------------------------------------------B_e---------------------------------B_f--------------->
頁面用的page-size=4
頁面排序:time
:
[A_a,A_b,A_c,B_d] [A_d,A_e,A_f,A_g] [A_h,A_i,B_e,A_j] [A_k,A_l,B_f,A_m]
它的工作原理,但也許是一個更有效的解決方案存在。請您指出正確的方向。
也許更適合於[代碼評審]中心( https://codereview.stackexchange.com/)。 – jwvh
另一點是,沒有什麼能阻止你詢問所有異步查詢(它可能會比順序詢問它們要快),但你仍然會受到db性能的瓶頸 – Nils