2013-09-21 44 views
0

有没有更好的方式在SQL Server中进行分页?更好的SQL分页技术

例如,我要补充@skip使用以下方法来@take:

;WITH tmp_cte AS (
SELECT ROW_NUMBER() OVER (ORDER BY LastName) AS RowNumber, 
     LastName, 
     FirstName 
    FROM person.Person 
    WHERE FirstName like '%ad%' 
) 
SELECT * 
FROM tmp_cte 
WHERE RowNumber > @skip --10 
AND RowNumber <= @Take--20 

有没有更好的办法,这样我就不用加跳跃服用?

+1

主要性能问题将成为'姓LIKE“%AD%”'条件,其次分页(这将是大偏移量的问题,如果总共有多少行符合上述姓名条件。 ) –

+0

@ypercube:不同意。主要问题是这个解决方案和最大数量的解决方案。的选票并不好。这些解决方案需要更大的索引,并且当页码很大时(在ORDER BY LastName的“末尾”),性能会变差。 –

回答

6

在SQL 2012这很简单:

SELECT LastName, FirstName 
    FROM person.Person 
WHERE FirstName like '%ad%' 
ORDER BY LastName 
OFFSET 10 ROWS 
FETCH NEXT 10 ROWS ONLY; 

的SQL服务器+性能对比其他版本退房this link

0

如果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子句中更多的列。