2017-06-02 171 views
2

我在MSSQL(1億條記錄)有兩個相當大的模式相同的表,我需要創建一個SP,返回一個帶有如下定義的查詢的聯合結果集。 在某些情況下,結果可能僅僅是幾條記錄,而在其他情況下,結果可能會有數百萬,具體取決於SP的輸入。我還需要在「S」值上對它進行排序,這是一個類似Guid的值,即非順序值。使用UNION ALL時的ORDER BY - 利用索引?

從一個表單獨加載(即沒有UNION ALL)時,排序可以充分利用索引並進行有效排序,但是UNION ALL會如何影響排序呢?

使用這些值的客戶端應用程序想要獲得一個數據流,即我們不希望等待所有記錄被讀取/加載才能返回第一組「S」匹配。

-- Creates #distinctMatches temporary table etc. above.. 

CREATE CLUSTERED INDEX idx ON #distinctMatches (s) 

SELECT 
    'C' AS [source] 
    ,P.[Id] 
    ,P.[A] 
    ,P.[B] 
    ,P.[C] 
    ,P.[D] 
    ,P.[E] 
    ,C.[S] AS [sortValue] 
FROM 
    [dbo].[data_current] AS P 
    INNER JOIN #distinctMatches AS C ON P.[s] = C.[s] 

UNION ALL 

SELECT 
    'A' AS [source] 
    ,P.[Id] 
    ,P.[A] 
    ,P.[B] 
    ,P.[C] 
    ,P.[D] 
    ,P.[E] 
    ,C.[S] AS [sortValue] 
FROM 
    [dbo].[data_archive] AS P 
    INNER JOIN #distinctMatches AS C ON P.[s] = C.[s] 
ORDER BY [sortValue] 

我還沒有能夠驗證這個操作順序是否可以利用索引或沒有?

我試圖閱讀查詢計劃,但未能在此解釋它們。 任何想法或替代建議?

這是一個傳統的應用程序,所以架構的大型架構/數據更改或其他主要重新設計在這一點上是不可能的。從下面的答案

UPDATE基於信息:

FROM 
    [dbo].[data_archive] AS P 
WHERE EXISTS (SELECT C.[s] FROM #distinctMatches AS C WHERE P.[s] = C.[s]) 
ORDER BY [sortValue] 

我能得到一個合併通過改變

FROM 
    [dbo].[data_archive] AS P 
    INNER JOIN #distinctMatches AS C ON P.[s] = C.[s] 
ORDER BY [sortValue] 

加入,而不是串聯。 (請參閱下面的答案)。

+0

請注意,列名/表只是示例名稱的場景,即它不被稱爲a,b,c等。 – jmw

+0

您是否知道您只訂購第二個結果集?你將不得不像SELECT * FROM(Select ... union Select ...)這樣的子查詢順序...在這種情況下,索引不會被使用。在sql server中有幾種排序算法,可以在查詢計劃中看到。我建議你應該對這些進行一些閱讀。 – PacoDePaco

+1

@PawełKucharski實際上是不正確的,使用UNION ALL ORDER BY適用於整套,不僅適用於最後一個。 我會研究訂購算法,謝謝。 – jmw

回答

1

你說過:「當從一個表單獨加載(即沒有UNION ALL)時,排序可以利用索引並有效地進行排序」所以表中有一個帶有主鍵列S的PK或至少一個覆蓋索引與領先的關鍵列S,這兩個表都是如此。這意味着查詢中的所有連接都是MERGE連接(臨時表的連接也位於排序列上),因此計劃中不會有任何其他排序

+0

我們有包含排序列(S)的索引,據我所知,它應該足以能夠在查詢優化器知道第一組「S」匹配後立即開始執行密鑰查找找到。 像這裏描述的那樣: http://use-the-index-luke.com/sql/sorting-grouping/indexed-order-by 即,查詢計劃中甚至沒有顯示SORT操作,但我不知道如何實現使用UNION ALL – jmw

+0

不,只是在索引中具有排序列是不夠的。它應該是索引的主要欄目,如果不是,它將在計劃中排序運營商 – sepupic

+0

你是對的,這就是我的意思,感謝clairifying。 – jmw