设为首页 收藏本站
查看: 1371|回复: 0

[经验分享] 分页控件之分页算法 —— for SQL Server 版。

[复制链接]

尚未签到

发表于 2015-6-30 11:03:51 | 显示全部楼层 |阅读模式
上两篇随笔:
我的分页控件(未完,待续)——控件件介绍及思路

我自己写的一个分页控件(源码和演示代码)PostBack分页版 for vs2003、SQL Server

关于分页的误区
    误区1:分页的时候,只有使用存储过程,效率才高。
    误区2:忽略了索引的作用。

上两篇好像介绍的不太详细,这里详细说明一下分页控件里使用的分页算法,也就是SQL语句。

分页一般分为四种情况

1、单字段排序,排序字段没有重复值。
2、单字段排序,排序字段有重复值。
3、多字段排序,最后一个排序字段没有重复值。
4、多字段排序,最后一个排序字段有重复值。

其中第2、4 情况都可以再加一个排序字段(比如说主键),就可以转换成第三种情况。

所以分页针对1、3两种情况设置了两种分页算法。

1、单字段排序,排序字段没有重复值。

    公式:


1 DSC0000.gif declare @col int
2
3select top {PageSize * (PageIndex-1)+1} @col = [排序字段]
4from [表名|视图名]
5[ where 查询条件 ]
6order by [排序字段] asc|desc
7
8select top PageSize 需要显示的字段
9from [表名|视图名]
10where [排序字段] >= @col
11[ and 查询条件 ]
12order by [排序字段] asc|desc
    以NorthWind 数据库里的 Products 表为例,假设一页显示10条数据,CategoryID = 3 为查询条件,按照ProductID 倒序,如果想显示第二页的数据,那么SQL语句就是
   
declare @col int

select top 11 @col = ProductID from Products where CategoryID = 3 order by ProductID desc   

select top 10 * from Products where ProductID >= @col and CategoryID = 3 order by ProductID desc   
   说明:
    第一行的定义,要根据字段类型来修改,看是比较麻烦,但是这个麻烦交给分页控件就可以了,使用者,只要设置分页控件的属性就可以了。
    第五行和第十一行,如果需要加查询条件的话就可以在这里添加。

    第三行是一个“定位”,这个可以算是SQL Server 所特有的吧,也是SQL Server 很宽容的地方。以Products 表的例子,执行完第一条select 语句之后, @col 里面记录的是 在CategoryID = 3 的记录里面,按照ProductID 倒序,排行在11位的记录的值。
   
    第一个select 语句定位以后,第二个select 语句就可以根据这个“位置”继续向下查找数据了。

    虽然例子里面使用了ProductID(主键)来排序,但是并不是说这个算法只能用主键来排序,哪个字段都可以,但是要符合第一种情况,就是“只有一个排序字段,且排序字段里的记录没有重复值”!


3、多字段排序,最后一个排序字段没有重复值。

    如果 Products 表想要用 UnitPrice 字段来排序怎么办呢?上面的算法是不适合的,我们需要使用另一种算法,这个和颠颠倒倒法有些类似,但是我做了一些优化。

    公式:

select [需要显示的字段] from [表名|视图名] where [主键字段] in

    ( select top PageSize [主键字段] from
        (select top {PageSize * PageIndex} [主键字段] , [排序字段] from     --有几个排序字段就写几个字段

            [表名|视图名]
            [ where 查询条件 ]
            order by
            
                [排序字段1] asc|desc ,
                [排序字段2] desc|asc,
                DSC0001.gif
                [主键字段] asc|desc     
        ) as aa     
        order by     
            [排序字段1] desc|asc,        --如果上面是倒序,那么这里就是正序,下同
                [排序字段2] asc|desc ,
                    
                    [主键字段] desc|asc

    )

order by
    [排序字段1] asc|desc,    --如果上面是倒序,那么这里就是正序,所谓颠颠倒倒嘛。
    [排序字段2] desc|asc,
   
    [主键字段] asc|desc
    以NorthWind 数据库里的 Products 表为例,假设一页显示10条数据,CategoryID = 3 为查询条件,按照UnitPrice 倒序,由于UnitPrice 字段可能有重复值,所以加上一个排序字段——ProductID ,即按照 UnitPrice desc,ProductID  来排序。 如果想显示第二页的数据,那么SQL语句就是

select * from Products where ProductID in
    ( select top 10 ProductID from
        (select top 20 ProductID , UnitPrice from     
            Products
            where CategoryID = 3
            order by
                UnitPrice desc ,
                ProductID      
        ) as aa     
        order by     
            UnitPrice asc,        --如果上面是倒序,那么这里就是正序,下同
                ProductID desc
    )
order by
    UnitPrice desc,    --如果上面是倒序,那么这里就是正序,所谓颠颠倒倒嘛。
    ProductID
    说明:
    1、这里查询条件加一次就可以了。
    2、是不是看 asc|desc 倒来倒去的有点晕,恩,这就对了,颠颠倒倒嘛。
    3、最主要的就是第三个select 语句,他要取从第一条数据到要显示的页的数据,可见越是后面的记录,top n 就会越大,所以这里提取的数据就要做一个精简,只写排序需要的字段(主键字段和排序字段)。
    4、第二个select 语句是去掉前面不需要的页里的数据,只保留要显示的页号里的数据。
    5、第一个select 语句,用主键字段 in () 的方式提取其他需要的字段。
    6、这种分页算法有一个小的bug,就是显示最后一页数据的时候,会多出来几条记录,不过这个bug已经在分页控件里面修正了,最后一页的分页算法,采用特殊的select语句。
    7、效率,设置好索引,效率是没有问题的,上一篇随笔已经测试过了。
    8、这种算法有一个“侵入性”,就是要求表必须有主键,而且不能是联合主键,引为要用 in 的方式查询数据。但是并没有要求主键自身必须能够排序。

测试效果
记录数:2523136条。
一页显示5条记录。

  //分页算法1 单字段排序,且排序字段是聚集索引。
   //1000 页以内 15毫秒
   //10000页以内 30毫秒
   //50000页以内 100多毫秒
   //100000页以内 200多毫秒
   //最后几页 第一次跳转到 4秒多
   //最后几页 连续向前翻页 1秒156毫秒

     //页号大范围跳转的时候需要的时间比较长,但是也小于1秒,同时SQL Server 占用的内存有所增加 120M。最后几页时达到320M
  ===================================================================
以下是多排序字段的分页情况,排序字段是 UnitPrice,ProductID  

   //分页算法2 无索引  首页 8秒187毫秒 。
   //10 页以内 2秒812毫秒
   //速度太慢下面的就不测试了
  //分页2 非聚集索引 UnitPrice  首页 468毫秒
   //10 页以内 2秒671毫秒
   //速度太慢下面的就不测试了
  
   //分页算法2 非聚集索引 UnitPrice,ProductID  首页 500毫秒
   //10 页以内 2秒796毫秒
   //100页以内 4秒796毫秒
   //速度太慢下面的就不测试了
  
   //分页算法2 非聚集索引 UnitPrice,ProductID desc  首页 500毫秒
   //10 页以内 0-15毫秒
   //100页以内 15-46毫秒
   //1000页以内 31-62毫秒
   //10000页以内 100毫秒左右
   //50000页以内 400-500毫秒
   //100000页以内 900毫秒左右
   //最后几页 第一次跳转到 4秒421毫秒
   //最后几页 连续向前翻页 4秒375毫秒
  //页号大范围跳转的时候需要的时间比较长,但是也小于1秒,
   //这回SQL Server 占用的内存增加幅度不大 120M左右



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-81877-1-1.html 上篇帖子: 在SQL Server 2005中创建数据库镜像的步骤及事项 下篇帖子: SQL Server 2005------分区表和分区函数
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表