如果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的“末尾”),性能会变差。 –