2017-10-21 167 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谢谢,非常感谢 –

相关问题