如果Person.Person表上存在唯一索引(例如PersonID
列上有一個唯一索引,並且此索引是羣集的 - 例如,如果您具有羣集PK),則可以有更好的解決方案。在這種情況下上面的查詢因此可以改寫爲:
;WITH tmp_cte AS (
SELECT ROW_NUMBER() OVER (ORDER BY LastName) AS RowNumber, PersonID
FROM person.Person
WHERE FirstName like '%ad%'
)
SELECT ...
FROM Person.Person p
WHERE p.PersonID IN -- PersonID is the key of this UNIQUE INDEX
(
SELECT PersonID FROM tmp_cte
WHERE RowNumber > @skip 10 AND RowNumber <= @Take--20
)
或
DECLARE @Rows TABLE (ID INT PRIMARY KEY);
;WITH tmp_cte AS (
SELECT ROW_NUMBER() OVER (ORDER BY LastName) AS RowNumber, PersonID
FROM person.Person
WHERE FirstName like '%ad%'
)
INSERT @Rows (ID)
SELECT PersonID FROM tmp_cte
WHERE RowNumber > @skip 10 AND RowNumber <= @Take--20
SELECT ...
FROM Person.Person p
WHERE p.PersonID IN (SELECT ID FROM @Rows); -- PersonID is the key of this UNIQUE INDEX
注#1:在此特定情況下,在(FirstName, LastName)
或(LastName, FirstName)
索引也是有用的。
注意2:該解決方案應該有更好的表現,如果你有最終SELECT
子句中更多的列。
主要性能問題將成爲'姓LIKE「%AD%」'條件,其次分頁(這將是大偏移量的問題,如果總共有多少行符合上述姓名條件。 ) –
@ypercube:不同意。主要問題是這個解決方案和最大數量的解決方案。的選票並不好。這些解決方案需要更大的索引,並且當頁碼很大時(在ORDER BY LastName的「末尾」),性能會變差。 –