更好的SQL分页技术

更好的SQL分页技术,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,在SQL server中有更好的分页方法吗 例如,我必须使用以下技术将@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

在SQL server中有更好的分页方法吗

例如,我必须使用以下技术将@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

有没有更好的方法,这样我就不必添加skip来获取?

在SQL 2012中,它非常简单:

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

查看其他版本的SQL Server+性能比较。

在SQL 2012中,它非常简单:

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

查看其他版本的SQL Server+性能比较。

如果Person.Person表ex上有唯一索引,则可能有更好的解决方案。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
)

注1:在这种特殊情况下,关于FirstName、LastName或LastName、FirstName的索引也很有用


注2:如果最终SELECT子句中有更多列,则此解决方案的性能会更好。

如果Person.Person表上有唯一索引,则可能有更好的解决方案。例如,如果您有一个聚集的PK,PersonID列上有唯一索引,并且此索引是聚集的。在这种情况下,可以重写上述查询,因此:

;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
)

注1:在这种特殊情况下,关于FirstName、LastName或LastName、FirstName的索引也很有用


注2:如果final SELECT子句中有更多列,则此解决方案的性能会更好。

主要性能问题将是类似“%ad%”的FirstName条件,其次是分页,这将是一个偏移量大的问题,并且如果总共有许多行与上述FirstName条件相匹配。@ypercube:不同意主要问题是这个解决方案和投票数最大的解决方案不能很好地扩展。这些解决方案需要更大的索引,并且当按姓氏排序的末尾的页码较大时,性能会变得更差。主要的性能问题将是类似于“%ad%”条件的姓氏,其次是分页,这将是一个偏移量较大的问题,如果总共有许多行与上述姓氏匹配条件。@ypercube:不同意。主要问题是这个解决方案和投票数最大的解决方案不能很好地扩展。这些解决方案需要更大的索引,当按姓氏排序的末尾的页码较大时,性能会变得更差。