一套新的SqlServer2005分页方案,很实用,很快!

一套新的SqlServer2005分页方案,很实用,很快!,第1张

概述感谢大家的讨论,我总结一下集中讨论的焦点: 1、为什么要使用row方案: 在oracle里有row_number虚列, mySql有limit关键字分页, 他们都有一个比较通用的分页方案, 使得hibernate等类似的程序可以拼接sql字符串提供通用的分页。 而sqlserver却没有这样的分页方案。 于是乎,本人稍稍改装row_number()over(order by )用法,获得了一个通用 感谢大家的讨论,我总结一下集中讨论的焦点:

1、为什么要使用row方案:
在oracle里有row_number虚列,
MysqL有limit关键字分页,
他们都有一个比较通用的分页方案,
使得hibernate等类似的程序可以拼接sql字符串提供通用的分页。
而sqlserver却没有这样的分页方案。
于是乎,本人稍稍改装row_number()over(order by )用法,获得了一个通用的分页方案。
如提供了sql如下:
sql code
                       select                 *                 from         Student         where         Age        >        18                 order                 by         Age       

被row方案的分页程序处理后变成
(在select 后面添加 top 开始位置 0 __tc,在外层嵌套固定模式的查询sql)
sql code
                       select                 *                 from         (         select         row_number()        over        (        order                 by         __tc__)__rn__,        *                 from         (        select                 top         开始位置        +        10                 0         __tc__,        *                 from         Student         where         Age        >        18                 order                 by         Age)t )tt         where         __rn__        >        开始位置       

这样就得到了拼接出通用的分页sql方案了。
并且经过本人测试发现,这套方案的运行速度不逊于任何一套其他方案。
其余各方面效率还有待考察,忘高人指点了。

2、row方案的排序:
row方案可以任意排序,
只要修改最内层的select排序即可,
应该来说是很简单易用的。
参考【追加说明1、】和【#80楼】。

3、row方案和普通row_number()方案的区别:
一般的row方案:
sql code
                       select                 *                 from         (        select                 top         开始位置        +        10         row_number()        over        (        order                 by         ID)__rn__,        *                 from         Student)t         where         __rn__        >=        开始的位置       

使用了over(order by 表中的列),照成了必须由用户提供这个列,
而不容易使用分页程序生成分页sql(如hibernate分页)。
而row方案使用的是一个常数列tempColumn,值永远是0。
sql code
                       select                 *                 from         (         select         row_number()        over        (        order                 by         TempColmun)         *                 from         (         select                 top         开始的位置         0                 as         TempColmun,        *                 from         Student         order                 by         ID )tt)t         where         rowNumber         >=        开始的位置       

这个列是静态的,只是为了使用row_number()函数,
并不是真正的order by 依据,order by 实际看最内层。

我分析是因为row方案使用一个静态的列tempColumn,
这样可能被sql分析程序认为是无需排序的,省下了排序过程的开销。

4、数据测试:
现只在我一台机子上试过,
希望路过的各位随手帮忙测试一下。
这也是我迟迟不结贴的缘故。
举手之劳,复制sql运行即可:
sql code
                       --        插入测试数据200w条,可能会很久                 create                 table         Student( ID         int                 PRIMARY                 KEY                 IDentity        (        1        ,        1        ),name         nvarchar        (        50        ),Age         int         )         insert         Student(name,Age)        values        (        '        name        '        ,        18        )         while         (        select                 count        (        *        )         from         Student)        <        2000000                 insert         Student         select         name,Age         from         Student       

运行测试代码:
sql code
                       --        开始测试查询                 declare                 @Now                 datetime                 --        max方案                 select                 '        max        '        方案         select                 @Now        =        getdate        ()         --        begin                 select                 top                 10                 *                 from         Student         where         ID        >        (         select                 max        (ID)         from         (         select                 top                 1999990         ID         from         Student         order                 by         ID)tt)         --        end                 declare                 @maxDiff                 int                 select                 @maxDiff        =        datediff        (ms,        @Now        ,        getdate        ())         --        top方案                 select                 '        top        '        方案         select                 @Now        =        getdate        ()         --        begin                 select                 top                 10                 *                 from         Student         where         ID         not                 in        (        select                 top                 1999990         ID         from         Student)         --        end                 declare                 @topDiff                 int                 select                 @topDiff        =        datediff        (ms,        getdate        ())         --        row方案                 select                 '        row        '        方案         select                 @Now        =        getdate        ()         --        begin                 select                 *                 from         (         select         row_number()        over        (        order                 by         tc)rn,        *                 from         (        select                 top                 2000000                 0         tc,        *                 from         Student)t )tt         where         rn        >        1999990                 --        end                 declare                 @rowDiff                 int                 select                 @rowDiff        =        datediff        (ms,        getdate        ())         --        row_number方案                 select                 '        row_number        '        方案         select                 @Now        =        getdate        ()         --        begin                 select                 *                 from        (         select                 top                 2000000         row_number()        over        (        order                 by         ID)rn,        *                 from         Student )t         where         rn        >        1999990                 --        end                 declare                 @row_numberDiff                 int                 select                 @row_numberDiff        =        datediff        (ms,        getdate        ())         --        记录结果                 select                 '        第20万页        '        页码,        @maxDiff         max方案,        @topDiff         top方案,        @rowDiff         row方案,        @row_numberDiff         row_number方案       


-----------------------------------------------------------
以下为原帖:
-----------------------------------------------------------

这套方案(下面简称row方案)是本人借鉴Oracle的row_number分页方法和sqlServerrow_number结合+上top分页方案合体版,经过本人初步测试。
效率非常快。(本人测试非常业余,还望高人帮忙测试。)
row方案的具体 *** 作方法在这章帖子里:
一套原创的sqlserver通用分页方案 忘高人测试效率 先阿里嘎多了

比较了3种分页方式,分别是max方案,top方案,row方案

效率:
  第1:row
  第2:max
  第3:top

缺点:
  max:必须用户编写复杂sql,不支持非唯一列排序
  top:必须用户编写复杂sql,不支持复合主键
  row:不支持sqlServer2000

测试数据:
320万条数据,每页显示 10条数据,分别测试了 2万页、 15万页和 32万页。

页码, top方案max方案row方案
2万, 60ms46ms33ms
15万, 453ms343ms310ms
32万, 953ms720ms686ms


具体 *** 作sql代码如下:

top方案:
sql code
              select                 top                 10                 *                 from         table1         where         ID         not                 in        (        select                 top         开始的位置 ID         from         table1)      

max:
sql code
              select                 top                 10                 *                 from         table1         where         ID        >        (        select                 max        (ID)         from         (        select                 top         开始位置 ID         from         table1order         by         ID)tt)      

row:
sql code
              select                 *                 from         (         select         row_number()        over        (        order                 by         tempColumn)tempRowNumber,        *                 from         (        select                 top         开始位置        +        10         tempColumn        =        0        ,        *                 from         table1)t )tt         where         tempRowNumber        >        开始位置      
总结

以上是内存溢出为你收集整理的一套新的SqlServer2005分页方案,很实用,很快!全部内容,希望文章能够帮你解决一套新的SqlServer2005分页方案,很实用,很快!所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1178953.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存