本文介紹了在SQL Server中是否有更好的選項來應(yīng)用分頁而不應(yīng)用偏移量?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我想對包含大量數(shù)據(jù)的表應(yīng)用分頁。我只想知道一個比在SQL Server中使用偏移量更好的選項。
以下是我的簡單查詢:
SELECT *
FROM TableName
ORDER BY Id DESC
OFFSET 30000000 ROWS
FETCH NEXT 20 ROWS ONLY
推薦答案
您可以使用Keyset Pagination進行此操作。它比使用行集分頁(按行號分頁)far more efficient要好。
在行集分頁中,必須先讀取前面的所有行,然后才能讀取下一頁。而在鍵集分頁中,服務(wù)器可以立即跳到索引中的正確位置,因此不會讀取不需要的額外行。
在這種類型的分頁中,您不能跳到特定的頁碼。你跳到一個特定的鍵上,從那里開始閱讀。為了很好地執(zhí)行此操作,您需要對該鍵具有唯一索引,該索引包括您需要查詢的任何其他列。
除了明顯的效率提升外,
的一大好處是避免了分頁時由于從以前讀取的頁面中刪除行而導致的";漏行問題。按鍵分頁時不會發(fā)生這種情況,因為鍵不會更改。
下面是一個示例:
假設(shè)您有一個名為TableName
的表,其索引位于Id
,并且您希望從最新的Id
值開始并向后工作。
開始時:
SELECT TOP (@numRows)
*
FROM TableName
ORDER BY Id DESC;
請注意使用
ORDER BY
以確保順序正確
客戶端將保留最后接收的Id
值(在本例中為最低值)。在下一個請求時,您跳到該鍵并繼續(xù):
SELECT TOP (@numRows)
*
FROM TableName
WHERE Id < @lastId
ORDER BY Id DESC;
注意
<
Not<=
的用法
如果您想知道,在典型的B-Tree+索引中,具有指示ID的行是而不是讀取的,它是之后的被讀取的行。
所選的鍵必須唯一,因此,如果按非唯一列分頁,則必須向ORDER BY
和WHERE
添加第二列。例如,您需要OtherColumn, Id
上的索引來支持這種類型的查詢。不要忘記索引上的INCLUDE
列。
SQL Server不支持行/元組比較器,因此您無法執(zhí)行(OtherColumn, Id) < (@lastOther, @lastId)
(但在PostgreSQL、MySQL、MariaDB和SQLite中支持)。
相反,您需要以下各項:
SELECT TOP (@numRows)
*
FROM TableName
WHERE (
OtherColumn = @lastOther AND Id < @lastId)
OR OtherColumn < @lastOther
)
ORDER BY
OtherColumn DESC,
Id DESC;
這比看起來更有效,因為SQL Server可以將其轉(zhuǎn)換為兩個值上的正確<
。
的存在使事情變得更加復雜。您可能需要分別查詢這些行。
這篇關(guān)于在SQL Server中是否有更好的選項來應(yīng)用分頁而不應(yīng)用偏移量?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,