2013-09-21 66 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子句中更多的列。