我有一個程序,我的用戶可以用它查找過去7天發生的所有數據流量。我使用存儲過程來獲取數據 - 每次有250條記錄(用戶可以通過該頁面進行翻頁)。問題是,當用戶想看到這些數據時,用戶會得到很多超時。SQL Server 2008等同於帶有WHERE子句的FETCH OFFSET
這是我試圖優化ist之前的存儲過程。
@MaxRecCount INT,
@PageOffset INT,
@IncludeData BIT
SELECT [Client], [Schema], [Version], [Records], [Fetched], [Receipted], [ProvidedAt], [FetchedAt], [ReceiptedAt],[PacketIds], [Record] FROM (
SELECT TOP(@MaxRecCount) MAX(bai_ExportPendingArchive.[UserName]) AS Client,
MAX(bai_ExportPendingArchive.Category) AS [Schema],
MAX(bai_ExportPendingArchive.ContractVersion) AS [Version],
COUNT(*) AS [Records],
SUM (CASE WHEN bai_ExportPendingAckArchive.ExportPendingId IS NULL THEN 0 ELSE 1 END) as [Fetched],
SUM (CASE WHEN bai_ExportPendingAckArchive.Receipted IS NULL THEN 0 ELSE 1 END) as [Receipted],
MAX(bai_ExportArchive.Inserted) AS [ProvidedAt],
MAX(CASE WHEN bai_ExportPendingAckArchive.ExportPendingId IS NULL THEN NULL ELSE bai_ExportPendingAckArchive.Inserted END) AS [FetchedAt],
MAX(CASE WHEN bai_ExportPendingAckArchive.Receipted IS NULL THEN NULL ELSE bai_ExportPendingAckArchive.Receipted END) AS [ReceiptedAt],
bai_ExportArchive.PacketIds AS [PacketIds],
NULL AS [Record],
ROW_NUMBER() Over (Order By MAX(bai_ExportArchive.Inserted) desc) as [RowNumber]
FROM bai_ExportArchive
INNER JOIN bai_ExportPendingArchive ON bai_ExportArchive.Id = bai_ExportPendingArchive.ExportId
LEFT OUTER JOIN bai_ExportPendingAckArchive ON bai_ExportPendingAckArchive.ExportPendingId = bai_ExportPendingArchive.Id
GROUP BY bai_ExportPendingArchive.[UserName], bai_ExportArchive.PacketIds, bai_ExportPendingArchive.Category
) AS InnerTable WHERE RowNumber > (@PageOffset * @MaxRecCount) and RowNumber <= (@PageOffset * @MaxRecCount + @MaxRecCount)
ORDER BY RowNumber
@MaxRecCount,@PageOffset和@IncludeData是那些從我的C# - 方法參數。 這個版本需要大約1:35分鐘才能獲得我想要的數據。爲了使存儲過程更快的I insered WHERE子句來篩選插入的山坳(也是我做了這列的索引),並使用OFFSET FETCH:
存儲過程的優化後:
@MaxRecCount INT,
@PageOffset INT,
@IncludeData BIT
Declare @pageStart int
Declare @pageEnd int
SET @pageStart = @PageOffset * @MaxRecCount
SET @pageEnd = @pageStart + @MaxRecCount + 50
IF @IncludeData = 0
BEGIN
SELECT [Client], [Schema], [Version], [Records], [Fetched], [Receipted], [ProvidedAt], [FetchedAt], [ReceiptedAt],[PacketIds], [Record] FROM (
SELECT TOP(@MaxRecCount) bai_ExportPendingArchive.[UserName] AS Client,
bai_ExportPendingArchive.Category AS [Schema],
MAX(bai_ExportPendingArchive.ContractVersion) AS [Version],
COUNT(*) AS [Records],
SUM (CASE WHEN bai_ExportPendingAckArchive.ExportPendingId IS NULL THEN 0 ELSE 1 END) as [Fetched],
SUM (CASE WHEN bai_ExportPendingAckArchive.Receipted IS NULL THEN 0 ELSE 1 END) as [Receipted],
MAX(bai_ExportArchive.Inserted) AS [ProvidedAt],
MAX(CASE WHEN bai_ExportPendingAckArchive.ExportPendingId IS NULL THEN NULL ELSE bai_ExportPendingAckArchive.Inserted END) AS [FetchedAt],
MAX(CASE WHEN bai_ExportPendingAckArchive.Receipted IS NULL THEN NULL ELSE bai_ExportPendingAckArchive.Receipted END) AS [ReceiptedAt],
bai_ExportArchive.PacketIds AS [PacketIds],
NULL AS [Record],
ROW_NUMBER() Over (Order By MAX(bai_ExportArchive.Inserted) desc) as [RowNumber]
FROM bai_ExportArchive
INNER JOIN bai_ExportPendingArchive ON bai_ExportArchive.Id = bai_ExportPendingArchive.ExportId
LEFT OUTER JOIN bai_ExportPendingAckArchive ON bai_ExportPendingAckArchive.ExportPendingId = bai_ExportPendingArchive.Id
Where bai_ExportArchive.Inserted <= (Select bai_ExportArchive.Inserted from bai_ExportArchive Order by bai_ExportArchive.Inserted DESC Offset @pageStart ROWS FETCH NEXT 1 ROWS Only)
And bai_ExportArchive.Inserted > (Select bai_ExportArchive.Inserted from bai_ExportArchive Order by bai_ExportArchive.Inserted DESC Offset @pageEnd ROWS FETCH NEXT 1 ROWS Only)
GROUP BY bai_ExportPendingArchive.[UserName], bai_ExportArchive.PacketIds, bai_ExportPendingArchive.Category
) AS InnerTable
ORDER BY RowNumber
這個版本給了我大約2s的數據。唯一的問題是,我在Microsoft SQL Server 2014上工作,但我的用戶使用SQL Server 2008+。現在的問題是,OFFSET FETCH dosn't在Server 2008中工作。現在我無能爲力,我可以優化我的存儲過程,它在SQl Server 2008上運行速度快。
我很感謝任何幫助:)
謝謝你的回答。說實話:我不知道如何將你的建議插入我的存儲過程。 – KatharinaG
您可以在CTE中替換您的選擇查詢,但'ROW_NUMBER()OVER(ORDER BY [put_column-to-sort-here] DESC)AS [ROW_NO]'列應該在那裏對記錄進行排序,那麼只有我們可以維護記錄中的訂單序列。 CTE之後的選擇腳本將保持不變。 –
好吧,現在我知道了,我改變了我的存儲過程,就像你建議的那樣,但是現在需要大約3分07分鐘才能得到我想要的數據(比如1:35分鐘) – KatharinaG