动态SQL最佳分页

时间:2015-02-26 03:18:49

标签: sql sql-server performance sql-server-2008-r2 paging

多年来,我一直在通过将ROW_NUMBER()包装到CTE中来创建动态sql分页。这种方法在stackoverflow中已经多次提及,并且它提供了良好的性能。

但是,由于sql server 2012引入了offsetfetch,性能更好,我决定看看我是否可以优化我的sql 2008 R2分页语句以匹配sql server 2012的性能。

这个blog entry描述了offset命令的一个非常有趣的替代方法:

WITH cteKeySeek
AS
(
SELECT 
       BusinessEntityID,
       LastName,
       ROW_NUMBER() OVER (ORDER BY LastName,BusinessEntityID)-1 AS RowN
  FROM Person.Person
)
SELECT 
      TOP(20) cteKeySeek.LastName,
      FirstName,
      cteKeySeek.BusinessEntityID,
      RowN
 FROM cteKeySeek
 INNER LOOP JOIN Person.Person   
 ON cteKeySeek.BusinessEntityID = Person.BusinessEntityID
 WHERE RowN >= 20 AND RowN<=39
 ORDER BY LastName,BusinessEntityID;

但是,上面提到的这个替代方法是使用索引表,而我需要的是动态sql。我尝试了几种方法为动态sql语句创建类似的实现但没有成功......性能比常规CTE / ROW_NUMBERS方法慢10倍。

这是迄今为止我可以创建的最佳实现:

WITH T1 AS ( << Your Dynamic SQL here >>  )
SELECT TOP 100 T2.RowN , T2.*
FROM (
  SELECT ROW_NUMBER() OVER ( ORDER BY WhateverField ) AS RowN, WhateverID, WhateverField
  FROM T1
) AS T2
INNER LOOP JOIN T1 ON T2.WhateverID  = T1.WhateverID 
WHERE T2.RowN BETWEEN 10000 AND 10999
ORDER BY WhateverField;

理想情况下,我更喜欢只涉及动态sql的解决方案......我知道有时存储过程可能会提供其他替代方案,但如果我必须在管理SP和迁移到SQL 2012之间做出选择,我会选择第二种选择。

0 个答案:

没有答案