大家来讨论讨论 -> 最佳的数据库分页方法

cwsj 2002-09-12 07:00:32
大家来讨论讨论 -> 最佳的数据库分页方法

下面的文章说:

客户端传递一个页码过去,然后SQLServer直接通过一次查询就生成所需的一页的记录集,并且以一个纪录集的形式返回给客户端,是最佳的分页方法。但是微软示范的分页方法是用只读快速游标取出某页的记录集,而不是在procedure中分页,难道微软的方法是低效率的?不明白。

最简单的方法是哪位高手能测试比较一下,得出一个结果。



转自:http://club.topdigi.com.cn/tech/shtm/sql/35.shtm

 一:一个老生常谈的问题。
    我们知道,记录集分页是数据库处理中十分常见的问题。而当我们设计到网络数据库,就是说要考虑传输带宽问题时,分页问题就每每困扰着每一个数据库程序设计人员。

二:分页问题的解决方案汇总
    说起解决的方案,每个数据库设计人员可能都会举出许多方法。但细分后,可以归为三类。一:Ado纪录集分页、二:专储记录集分页、三、数据库游标分页。
 一:著名的ADO纪录集分页。
     说到著名,因为这个可能是最简单和常见的分页方法了。(可能也是用的最多的)就是利用ADO自带的分页功能来实现分页。
二:转储纪录集分页。
这种方法诞生于网络时代,就是利用服务器端的强大处理过程,先将目标数据库存到一个临时的数据库里,并且加上一个自增字段来进行划分页面,最后将所需固定数目的纪录集传回。

第三种方法:服务器端游表选取纪录集的办法。
    这种办法属于很有争论的办法。
    它主要是用服务器端的游表选取纪录集,然后一次返回,也就是返回多个纪录集,每个纪录集就有一个纪录。然后用Recordset.nextrecord的方法来输出每一个纪录集。
    国外许多网站对此进行过考证,因为第一:Recordset.nextrecord具有这种方法的ADO.游表不是最快的火线游表,第二,许多人认为采用recordset.nextrecord方法输出时其实等于和服务器端交互了一次,所以这种方法属于那种当许多人并发访问数据库时,能导致数据库访问量成倍增。。。 
             
列举程序:(作者:bigeagle)
if exists(select * from sysobjects where ID = object_id("up_TopicList"))
   drop proc up_TopicList
go

create proc up_TopicList 
            @a_ForumID int , @a_intDays int , @a_intPageNo int , @a_intPageSize tinyint
   as
       declare @m_intRecordNumber int
       declare @m_intStartRecord  int
       select @m_intRecordNumber = @a_intPageSize * @a_intPageNo
       select @m_intStartRecord = @a_intPageSize * (@a_intPageNo - 1) + 1

       if @a_intDays = 0                      --如果不限定天数
          begin
                /*求符合条件记录数*/
                select "RecordCount" = count(*)                         
                       from BBS where Layer=1 and ForumID = @a_ForumID 

               /*输出纪录*/
               /*首先定义可滚动光标*/
               set rowcount @m_intRecordNumber
               declare m_curTemp Scroll cursor 
                       for
                          select a.ID ,a.Title , d.UserName , a.FaceID ,
                                'ContentSize' = datalength(a.Content) , 
                                'TotalChilds' = (select sum(TotalChilds) 
                                                        from BBS as b 
                                                        where a.RootID = b.RootID) ,
                                'LastReplyTime' = (select max(PostTime) 
                                                          from BBS as c 
                                                          where a.RootID = c.RootID)
                                from BBS as a 
                                     join BBSUser as d on a.UserID = d.ID 
                                where Layer=1 and ForumID = @a_ForumID 
                                order by RootID desc , Layer , PostTime
               open m_curTemp
               fetch absolute @m_intStartRecord from m_curTemp
               while  @@fetch_status = 0 
                      fetch next from m_curTemp

               set rowcount 0 
               /*清场*/       
               CLOSE m_curTemp
               DEALLOCATE m_curTemp
          end                      
                          
       else                                --如果限定天数          

          begin
                /*求符合条件记录数*/
                select "RecordCount" = count(*)                         
                       from BBS where Layer=1 and ForumID = @a_ForumID 
                                      and dateadd(day , @a_intDays , PostTime) > getdate() 

               /*输出纪录*/
               /*首先定义可滚动光标*/
               set rowcount @m_intRecordNumber
               declare m_curTemp Scroll cursor 
                       for
                          select a.ID ,a.Title , d.UserName , a.FaceID ,
                                'ContentSize' = datalength(a.Content) , 
                                'TotalChilds' = (select sum(TotalChilds) 
                                                        from BBS as b 
                                                        where a.RootID = b.RootID) ,
                                'LastReplyTime' = (select max(PostTime) 
                                                          from BBS as c 
                                                          where a.RootID = c.RootID)
                                from BBS as a 
                                     join BBSUser as d on a.UserID = d.ID 
                                where Layer=1 and ForumID = @a_ForumID 
                                      and dateadd(day , @a_intDays , PostTime) > getdate() 
                                order by RootID desc , Layer , PostTime
               open m_curTemp
               fetch absolute @m_intStartRecord from m_curTemp
               while  @@fetch_status = 0 
                      fetch next from m_curTemp

               set rowcount 0 
               /*清场*/       
               CLOSE m_curTemp
               DEALLOCATE m_curTemp
          end                                                
go


注:若在asp中调用存储过程的command
...全文
65 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
ji_hui 2002-09-13
  • 打赏
  • 举报
回复
这怎么是最佳的数据库分页方法?

最佳的数据库分页方法应直接用select * from table选出指定页的记录集!
用cursor的性能不好。
fightflag 2002-09-13
  • 打赏
  • 举报
回复
用sql语句来实现吧。一次只取出需要的一页,作为DataSet返回。

select top 5 * from tab_temp where [id] not in (select top 5 [id] from tab_temp order by [id] )

第2个select top 5中的5其实含义为1×5 这条语句返回第6到10条记录(每页5条记录)。

62,041

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧