zoukankan      html  css  js  c++  java
  • 几种分页算法。翻页必备

    1.“俄罗斯存储过程”的改良版

    CREATE procedure pagination1

    (@pagesize 
    int,  --页面大小,如每页存储20条记录

    @pageindex 
    int   --当前页码

    )

    as

    set nocount on

    begin

    declare @indextable table(id int identity(1,1),nid int)  --定义表变量

    declare @PageLowerBound int  --定义此页的底码

    declare @PageUpperBound int  --定义此页的顶码

    set @PageLowerBound=(@pageindex-1)*@pagesize

    set @PageUpperBound=@PageLowerBound+@pagesize

    set rowcount @PageUpperBound

    insert into @indextable(nid) select gid from TGongwen where fariqi >dateadd(day,-365,getdate()) order by fariqi desc

    select O.gid,O.mid,O.title,O.fadanwei,O.fariqi from TGongwen O,@indextable t where O.gid=t.nid

    and t.id>@PageLowerBound and t.id<=@PageUpperBound order by t.id

    end

    set nocount off

    文章中的点评:

    以上存储过程运用了SQL SERVER的最新技术――表变量。应该说这个存储过程也是一个非常优秀的分页存储过程。当然,在这个过程中,您也可以把其中的表变量写成临时表:CREATE TABLE #Temp。但很明显,在SQL SERVER中,用临时表是没有用表变量快的。所以笔者刚开始使用这个存储过程时,感觉非常的不错,速度也比原来的ADO的好。但后来,我又发现了比此方法更好的方法。

    我的感觉:

    没有做过测试,从感觉上讲,效率不是太高。



    2. not in 的方法:

    从publish 表中取出第 n 条到第 m 条的记录:
    SELECT TOP m-n+1 *
    FROM publish
    WHERE (id NOT IN
        (
    SELECT TOP n-1 id
         
    FROM publish))

    id 为publish 表的关键字

    文章中的点评:

    我当时看到这篇文章的时候,真的是精神为之一振,觉得思路非常得好。等到后来,我在作办公自动化系统(ASP.NET+ C#+SQL SERVER)的时候,忽然想起了这篇文章,我想如果把这个语句改造一下,这就可能是一个非常好的分页存储过程。于是我就满网上找这篇文章,没想到,文章还没找到,却找到了一篇根据此语句写的一个分页存储过程,这个存储过程也是目前较为流行的一种分页存储过程,我很后悔没有争先把这段文字改造成存储过程:
    (更多的内容,请查看原文。)

    我的感觉:

    使用了 not in  而 not in  是无法使用索引的,所以从效率上讲还是差了一点。


    2. max 的方法:

    select top 页大小 *

    from table1

    where id>

         (
    select max (id) from

         (
    select top ((页码-1)*页大小) id from table1 order by id) as T

          )    

     
    order by id

    文章中的点评:

    我们知道,几乎任何字段,我们都可以通过max(字段)或min(字段)来提取某个字段中的最大或最小值,所以如果这个字段不重复,那么就可以利用这些不重复的字段的max或min作为分水岭,使其成为分页算法中分开每页的参照物。在这里,我们可以用操作符“>”或“<”号来完成这个使命,使查询语句符合SARG形式。如:

    Select top 10 * from table1 where id>200

    我的感觉:

    这个就高高效了一点。但是不清楚 max的工作原理,不知道它的性能如何。


    下面的才是重点 —— 我研究的算法。如有雷同,属于英雄所见略同!

    1、追求高效的翻页算法 —— 定位法。

    declare @pageSize int   --返回一页的记录数
    declare @CurPage int  --页号(第几页)0:第一页;-1最后一页。

    declare @Count int
    declare @id int

    set @pageSize=10
    set @CurPage =1

    --定位
    if @CurPage = -1
    begin
     
    --最后一页
     set rowcount @pageSize
     
    select @id=newsID from newsTemp   order by newsID
    end

    if @CurPage > 0
    begin
     
    set @Count = @pageSize * (@CurPage -1+ 1
     
    set rowcount @Count
     
    select @id=newsID from newsTemp   order by newsID desc
    end

    --返回记录
    set rowcount @pageSize
    select * from newsTemp where newsID <=@id order by newsID desc

    set rowcount 0

    思路:就是上面的算法的延续,就是说呢避免使用  not in 和 max 的方法。

    也就是这个思路:Select top 10 * from table1 where id>200

    定位 —— 就是说要找到“临界点”,分页的临界点。找到了之后剩下的事情就好办了。

    缺点:单字段排序、排序字段的值不能重复(不是绝对不能重复,可以有少量的重复)。


    2、通用法 —— 颠颠倒倒法

    有的时候“定位法”的缺点是不可以接受的,但是没有关系,可以用这个的。

    select * from table where id in 
    (
     
    select top 10 ID from 
     (
      
    select top 20 ID,addedDate from table 
      
    order by addedDate desc
     ) 
    as aa order by addedDate
    )
    order by addedDate desc

    ID 是主键,addedDate 是排序字段。

    缺点:必须有主键。

  • 相关阅读:
    解决xcode5升级后,Undefined symbols for architecture arm64:问题
    第8章 Foundation Kit介绍
    app 之间发送文件 ios
    iphone怎么检测屏幕是否被点亮 (用UIApplication的Delegate)
    CRM下载对象一直处于Wait状态的原因
    错误消息Customer classification does not exist when downloading
    How to resolve error message Distribution channel is not allowed for sales
    ABAP CCDEF, CCIMP, CCMAC, CCAU, CMXXX这些东东是什么鬼
    有了Debug权限就能干坏事?小心了,你的一举一动尽在系统监控中
    SAP GUI和Windows注册表
  • 原文地址:https://www.cnblogs.com/MaxIE/p/350253.html
Copyright © 2011-2022 走看看