2017-10-21 126 views
1

如何優化此查詢,因爲EXT表每個包含大約150萬條記錄。我也有其他聯接,但他們的記錄相對少於50條。 都EXT表已設置與默認設置的身份和爲P需要關於具有多個連接的多百萬條記錄的優化查詢的建議

SELECT * 
FROM (
    SELECT 
    ROW_NUMBER() OVER(ORDER BY ID ASC) AS RowNumber 
    , * 
    FROM History 
    LEFT JOIN FlattenExt1 
     ON History.ID = FlattenExt1.ExtID 
    LEFT JOIN FlattenExt2 
     ON History.ID = FlattenExt2.ExtId 
) as final 
where final.RowNumber BETWEEN (@PageIndex -1) * @PageSize + 1 
          AND (((@PageIndex -1) * @PageSize + 1) + @PageSize) - 1 
order by final.rownumber 
+2

使用分享您的執行計劃[粘貼該計劃@ brentozar (https://www.brentozar.com/pastetheplan/)下面是說明:[如何使用粘貼計劃](https://www.brentozar.com/pastetheplan/instructions/)。 – SqlZim

+1

如前所述,共享您的表DDL和執行計劃。 –

+0

@artashes Khachatryan實際上,這只是一個代碼,在左連接方面需要優化。還有其他的內部連接,儘管這是必要的,但我在這裏沒有提到它。 –

回答

2

從什麼是可見的,我相信優化器的問題是知道如果左連接重複HISTORY.ID值,影響ROW_NUMBER運氣。 如果左連接條件都有參加的每排歷史0-1行限制,然後做對歷史的ROW_NUMBER感到孤獨,這些ID,然後再加入

DECLARE @page INT = 150 , @rows INT = 10 
;WITH 
data AS (SELECT ID FROM History) 
,rows (page, pages, rows) AS (SELECT @page, CEILING(CAST(COUNT(*) AS float)/@page), COUNT(*) FROM data) 
SELECT * FROM history INNER JOIN 
    (SELECT TOP (@rows) rowNumber,page, pages, rows,ID 
      FROM (SELECT row_number() OVER (ORDER BY ID ASC) rowNumber, * FROM rows, data) pagination 
      WHERE rowNumber > (@page-1) * @rows 
      order by rowNumber 
    )historypageids ON history.ID = historypageids 
LEFT JOIN FlattenExt1 ON History.ID = FlattenExt1.ExtID 
LEFT JOIN FlattenExt2 ON History.ID = FlattenExt2.ExtId 
+0

這個建議讓我大大優化了查詢時間,謝謝 –

0

這個答案的原始版本(通用SQL服務器)。

以下僅適用於SQL Server 2012+。

如果您不需要row_number()值,我建議:

SELECT . . . 
FROM History h LEFT JOIN 
     FlattenExt1 f1 
     ON h.ID = f1.ExtID LEFT JOIN 
     FlattenExt2 f2 
     ON h.ID = f2.ExtId               
ORDER BY h.ID 
OFFSET (@PageIndex -1) * @PageSize + 1 
FETCH NEXT @PageSize ROWS; 

這應該是能夠在History(ID)FlattenExt1(ExtId)FlattenExt2(ExtId)採取指數的優勢。

+0

我僅限於使用SQL2008R - –

+0

@ MonkeyD.luffy,我在版本中添加了特定於版本的標籤。 –

+0

@DanGuzman謝謝,非常感謝 –

相關問題