| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3330 人关注过本帖, 2 人收藏
标题:可按任意字段排序的百万级数据分页存储过程代码
取消只看楼主 加入收藏
天涯听雨
Rank: 2
来 自:东莞
等 级:论坛游民
威 望:4
帖 子:497
专家分:64
注 册:2007-8-25
结帖率:100%
收藏(2)
 问题点数:0 回复次数:2 
可按任意字段排序的百万级数据分页存储过程代码
一直从事大型网站开发,在许多时候都有分页过程。面对百万数据时分页过程显的尤为重要。并且这些需要分页的地方有一个共同的特点,那就是分页但并不是按ID(主键)来排序,而是要求按其他有重复值的列进行排序。比如,其中有一个页面,要列出将近十万条记录按点击进行排序。

    如果在代码中我们按如下方式进行请求,那速度不会知是如何的慢(数据在十万级上按点击进行排序)
    Dim Rs,SqlStr
    Set Rs=server.CreateObject("adodb.recordset")
    Rs.Open "Select * from Tab_News Order BY Hits desc",Conn,1,1

    Rs.pagesize=20
    Rs.AbsolutePage=Page

    利用上存储过程进行执行效果也令人不太满意!

    前面在编程论坛有发表过《百万级数据分页存储过程代码》,但以前所写分页都是必须按ID(主键,不重复)排序的优秀存储过程,但面对按任意字段(可能重复)也是无计可施。

    优秀的百万级数据分页存储过程代码(ver2.0)  https://bbs.bccn.net/viewthread.php?tid=180627
    优秀的百万级数据分页代码(Ver1.0)          http://bbs.

    上面所发表分页过程都必段是按主键排序

    在网上找了许多相关资料查看,终于找到有可以解决的指导方法,下面我把它行文如下,希望对大家有帮助



平台:Win2003+IIS6.0+Sql2000
'---------------------------------------------------------------------
'以下代码为网页代码

Response.Buffer = True
Dim SqlLocalName,SqlUsername,SqlPassword,SqlDatabaseName
Dim ConnStr,Conn

'----------------------------------------------------------------------
'SQL数据库
SqlLocalName ="(local)" '连接IP [ 本地用 (local) 外地用IP ]
SqlUsername ="sa" '数据库用户名
SqlPassword ="XXXXXX" '用户密码
SqlDatabaseName="NewsTable" '数据库名
ConnStr = "Provider=Sqloledb;User ID=" & SqlUsername & "; Password=" & SqlPassword & "; Initial Catalog = " & SqlDatabaseName & "; Data Source=" & SqlLocalName & ";"
On Error Resume Next
Set Conn=Server.CreateObject("ADODB.Connection")
Conn.open ConnStr

If Err Then
   err.Clear
   Set Conn = Nothing
   Response.Write "<div style='font-size:14px;color=#ff0000' align='center'>数据库连接出错,请检查数据库连接字串</div>"
   Response.End
End If

'本类进行实例化代码,不将所有可能性条件分页考虑进去。本类仅作参考
'--------------------------------------------------------------------------------------------
'PageNo     当前页;
'PageSizeX  分页大小;
'PageCountX 总页数;
'FieldCount 总记录数;
'StrWhere   查询条件;
'StrOrder   排序语句;

Dim PageNo,PageSizeX,PageCountX,FieldCount,StrWhere,StrOrder

'进行赋值
PageNo=trim(Request.Querystring("PageNo"))

PageSizeX=30 '定义分页大小
if isnumeric(PageNo) or PageNo="" then '如果没有Page值,进行初始化值
   PageNo=abs(PageNo)
   if PageNo=0 then PageNo=1
else
   PageNo=1
end if

'特别注意,StrWhere可以为空,但不能不进行赋值,为空时StrWhere="";StrOrder值不能为空,否则存储过程会出错
StrWhere=" (ClassCode=0101 and Hits>20) "
StrOrder=" Order BY Hits desc "


set recom = server.createobject(")
recom.activeconnection = Conn
= 4

= "GetPageRecord"
recom.Parameters.Append recom.CreateParameter("@StrWhere",202,1,200,StrWhere)
recom.Parameters.Append recom.CreateParameter("@StrOrder",202,1,200,StrOrder)
recom.Parameters.Append recom.CreateParameter("@PageSize",3,1,,PageSizeX)
recom.Parameters.Append recom.CreateParameter("@PageIndex",3,1,,PageNo)

set rs = recom.execute ()

if rs.bof and rs.eof then
   set rs=nothing : set recom=nothing : Conn.Close : set Conn=nothing
   response.write "没有找到任何记录"
   response.end
end if

'显示数据
do while not rs.eof
   response.write""&rs("Title")&"&nbsp;&nbsp;&nbsp;添加时间:"&rs("AddTime")&"<br/>"
   rs.movenext
loop

'取得记录总数,计算页数
set rs = rs.NextRecordset
if  rs("countx") > 0 then
    FieldCount=rs("countx")
else
    FieldCount=0
end if

'记算总页数
if (FieldCount mod PageSizeX)>0 then
    PageCountX=((FieldCount - (FieldCount mod PageSizeX))/ PageSizeX)+1
else
    PageCountX= (FieldCount / PageSizeX)
end if

'进行关闭和释放相关资源
set rs=nothing : set recom=nothing : Conn.Close : set Conn=nothing

'下面是翻页过程,这里我就不在提供了,详细代友请参照前两次版本


'--------------------------------------------------------
'以下代码为存储过程代码
CREATE Procedure GetPageRecord
(
@StrWhere  varchar(200),
@StrOrder  varchar(200),
@PageSize  int,
@PageIndex int
)
 
AS
/*
名称:GetPagingRecord
作用:按任意字段进行排序分页
作者:天涯听雨(2008-5-22)
声明:此代码你可以无偿使用及转载,但在转载时,请勿移称本文字声明
*/
 
  set nocount on
  Begin

  Declare @Sqlstr varchar(5000)
  Declare @StrCountSQL varchar(1000)
  Declare @StrWhereB varchar(100)
  Declare @PageLowerBound int   
  Declare @PageUpperBound int
  
  set @PageLowerBound=(@PageIndex-1)*@PageSize   
  set @PageUpperBound=@PageLowerBound+@PageSize  

  Create table #temp
  (
  RecNo int IDENTITY (1, 1) NOT NULL,
  Oldid int
  )

  set @Sqlstr=" Select ID from Tab_News "
   
  if(@StrWhere<>'')
    begin
    set @StrWhereB=@StrWhere+" and "
    set @StrWhere=" where "+@StrWhere
    end
  
  set @Sqlstr="insert into #temp(Oldid) "+@Sqlstr+@StrWhere+@StrOrder
  
  set rowcount @PageUpperBound
  exeCute(@Sqlstr)

  set @StrCountSQL="Select Count(ID) as countx from Tab_News "+@StrWhereA+""

  set @Sqlstr="Select * from Tab_News as a left join #temp as b on (b.Oldid=a.ID) where "+@StrWhereB+" b.RecNo>"+Cast(@PageLowerBound as varchar)+" and b.RecNo<="+Cast(@PageUpperBound as varchar)+@StrOrder

  exeCute(@Sqlstr)
  exeCute(@StrCountSQL)

  end
  set  nocount off
GO

    上面存储过程方法使用了这个临时表方案的存储过程,但由于临时表的建立与丢弃在读写磁盘上耗费太多时间也会导致该存储过程稳定性差,但对比前面我们进行的直接进行读取上速度提高不少,这也叫有所得也必有所失吧。对比下,利用临时表速度提高许多。

    面对临时表的所表现出来的性能差,我想应该还会有新的解决此问题,在不久时间,我还会上述方法进行改良!也将会在不久时间在编程论坛中发表。

    希望对大家有帮助
    如果需要转载,请标明出处,尊重作者的劳动

[[it] 本帖最后由 天涯听雨 于 2008-5-30 11:50 编辑 [/it]]
搜索更多相关主题的帖子: 字段 网站开发 数据 代码 
2008-05-22 13:26
天涯听雨
Rank: 2
来 自:东莞
等 级:论坛游民
威 望:4
帖 子:497
专家分:64
注 册:2007-8-25
收藏
得分:0 
一个这么好的帖沉了!

从明天起做幸福的人,喂马劈柴周游世界!
2008-05-26 10:14
天涯听雨
Rank: 2
来 自:东莞
等 级:论坛游民
威 望:4
帖 子:497
专家分:64
注 册:2007-8-25
收藏
得分:0 
没人关注,那也用不着写升级版本了。

从明天起做幸福的人,喂马劈柴周游世界!
2008-05-27 21:19
快速回复:可按任意字段排序的百万级数据分页存储过程代码
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018808 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved