如何优化此查询,因为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
答案 0 :(得分: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
答案 1 :(得分:0)
这回答了问题的原始版本(通用SQL Server)。
以下内容仅适用于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)
上的索引。