2017-08-16 45 views
1

我們有一種情況,我們需要將4個不同表中的結果組合成一個列表,並通過OFFSET/FETCH對其進行分頁。分段聯合所有結果 - 最佳性能

想要從表a,b,c選擇記錄d,按照CreatedDatetime排序,然後按OFFSET X排序。FETCH Y.表格非常大(按行數),聽起來很糟糕UNION ALL然後分頁,因爲這意味着可能會編譯整個記錄列表,然後再分頁。

問題是,沒有任何表可以作爲參考來提取開始/結束日期時間窗口,因爲每個集合可能但也可能不包含任何表中的記錄。例如,最終結果可能包含表a; a/b; a/b/c; a/b/c/d; b; b/c;....的任意組合的記錄,我們需要返回固定大小的數字(分頁大小,例如20)。

關於如何最有效地處理此問題的任何想法?

UPDATE

基於從@HABO 問題有不幸的是沒有什麼特別的線索,這樣有關查詢。我們在系統中顯示用戶活動。它有不同的種類(我們選擇的表格)。現在,查詢會彈出查看活動的管理員的數據。管理員如何看待數據可能會有很大的不同:一些用戶在過去幾個小時內會有數千個活動,管理員希望看到他們。在其他情況下,用戶將在一天中執行三項操作,管理員將只看到第一頁數據。

PS。這不是一個純粹的日誌表,因爲隨着時間的推移,活動充當狀態機,每個狀態都有其狀態,我們也在這些查詢中尋找狀態。

+1

確實的數據必須是實時的?索引視圖足夠了嗎?等待的開銷會被推遲到關閉時間,並且視圖上的索引可以提供您正在尋找的性能。它只是將工會的等待移動到更合適的時間。 – xQbert

+0

好吧,這是一個很好的問題。如果這樣做,那麼這不會是一個問題,如果沒有其他解決方案,我們會按照你的建議。但現在我想看看它是否有可能以可接受的方式實時做到這一點。 –

+0

我的意思是,我們可以通過添加一些假設來進行探測,例如,向後5小時將產生20個結果,如果不是,則返回更多...但這不是真正的SQL ... –

回答

0

這就是緩存有用的地方。您可以將查詢的結果緩存在應用程序層中,如果查詢的結果不是太大,可以在其中進行分頁,或者如果查詢的結果很大,則將查詢結果緩存在表(或臨時表)中。

1

如果您知道頁面大小(例如100),那麼您可以簡單地編寫4個前100個查詢(按創建日期排序) - 然後對結果進行聯合全部。 即使所有前100條記錄都來自您所涉及的1張表,也是如此。

對於後續尋呼查詢 - 你需要從每個表記錄最後一行顯示並以此作爲你的高水位標記爲下次提取 - (選擇前100 FROM表A凡行ID> @HighWater)

應該是相當有效的...

+0

這聽起來很有希望,我喜歡這種方法!肯定會嘗試這一個。感謝您的輸入! –

0

會有我想過濾器。從你說的話,這些可能會有很大的不同。所以在最壞的情況下,所有列都可以是過濾器。 我的建議是使用5個視圖,每個表和最後一個聯合他們。只要確保所有過濾器列儘可能簡單地上到物理表中即可。 最後,選擇主視圖並獲取,但要小心order by子句。確保按順序排列具有唯一的數據組合,否則您可能會遇到行簡單刷新時更改頁面的情況。如果有定義的用戶訂單,則強制在最後添加一些關鍵列。

如何安全地確保爲了通過以具有不同的值爲100%安全取出/偏移量:

在4次創建一個新的柱,用一個簡單的恆定數量的值,例如1,2,3,4 AS [TableSource] 請確保您選擇每個表的PK。如果您沒有,則必須在視圖中創建一個,例如可能使用ROW_NUMBER或NEWID作爲[Pk]。 最後,從主視圖中選擇時,你ORDER BY CreateDate,Pk,TableSource。通過這種方式,您可以100%安全地在同一組數據中將任何行放置在相同位置,從而實現正確的分頁。由CREATEDATE安全隔離的30行的次序頁面

例子:

SELECT * FROM (
SELECT src, id, ROW_NUMBER() OVER(ORDER BY dt DESC,src,id)rn FROM (
SELECT 1 src, id, dt FROM table1 /*WHERE x=y*/ UNION ALL 
SELECT 2 src, id, dt FROM table2 /*WHERE x=y*/ UNION ALL 
SELECT 3 src, id, dt FROM table3 /*WHERE x=y*/ UNION ALL 
SELECT 4 src, id, dt FROM table4 /*WHERE x=y*/)alltables 
)data WHERE data.rn BETWEEN 3001 AND 3030 
+0

問題是如何限制這4個視圖?回到每個視圖的日期時間? –

+0

除非實際擁有用戶過濾器,否則不需要按日期進行過濾。否則,假設用戶過濾例如通過知識產權,你如何按日期過濾?這不會錯誤地進一步限制結果嗎?除非有協議,例如1或2年的數據。在這種情況下,你可以,儘管最好自己歸檔表格。 –

+0

當然還有其他的過濾器,但是日期時間總是存在。所以,無論其他過濾器狀態如何,我們都需要日期時間排序想象一下無限的用戶活動集以及您應用的任何過濾器,您將始終需要30個按日期時間排序的活動。 –