有没有好的分页效果显著的储存过程。如动网论坛的贴子列表分页,他们的效率应该很高吧!

clkun 2003-12-29 12:57:07
期待有完整的解决方案!:)

不会的大家一直来顶!
...全文
38 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
yangzixp 2003-12-29
  • 打赏
  • 举报
回复
/*****听以前的同事说asp页面上的分页太慢了(如果数据多了),
就想了这么个笨办法。有些地方还要考虑----比如select top 22 * from cat_list
where T_id not in (select T_id from #change)是否有效率问题;数据不能重复等等
不过灵活性挺好。希望各位高手再给帮忙改正;多谢chair3的帮助---这个存储过程还可以在加入几个变量,随便大家改吧:)*****/


CREATE proc page
@pagenum int
as
SET NOCOUNT ON /*-----这一句很重要哦:)),不然它只会认 insert #change......这个数据集:))*/
declare @sql nvarchar(500) --声明动态sql执行语句
declare @pagecount int --当前页数

--取得当前数据库的记录总数
declare @row_num int
begin
select @row_num=count(*) from cat_list

--创建临时表,作为数据过滤
create table #change (T_id int)

--判断当前页数
if @row_num>6 --大于页面显示记录数,则分页
begin
set @row_num=@pagenum*6

if @row_num=6
select top 6 * from cat_list
else
begin
set @row_num=(@pagenum-1)*6
set @pagecount=@row_num
set @sql=N'insert #change (T_id) select top '+cast(@pagecount as char(100))+' T_id from cat_list where T_id not in (select T_id from #change)'
exec sp_executesql @sql
select top 6 * from cat_list where T_id not in (select T_id from #change)
end
end
else --只现实全部的数据
select * from cat_list
end
GO



客户端这样调用:
<!--#include file="conn.asp"-->
<!--#include file="adovbs.inc"-->
<% dim T_com
dim T_rs'declare datamanage recordset


dim parameters
set T_com=server.createobject("adodb.command")
T_com.ActiveConnection=conn
T_com.CommandText="page"
T_com.CommandType=adCmdStoredProc
'T_com.Prepared=true
set parameters=T_com.CreateParameter("@pagenum",adInteger,adParamInput)
T_com.Parameters.Append parameters
dim page
page=request.QueryString("page")
if page="" then
page=1
end if
T_com("@pagenum")=page
set T_rs=T_com.Execute

do while not T_rs.eof
response.Write T_rs("c_name")
T_rs.movenext
loop
%>
<a href="a.asp?page=<%=page+1%>">ddddd</a>


yangzixp 2003-12-29
  • 打赏
  • 举报
回复
set rowcount 方法不错,5000多页,只用不到1秒。
呵呵


看了几个朋友写的关于存储过程分页的文章,感觉有点问题。starleee和东方蜘蛛希望我能发表点看法,我简单说一下。

首先是allsky的那个分页方法根本就不成立,看看他是这样的:
select @iStart=(@iPage-1)*@iPageSize
select @iEnd=@iStart+@iPageSize+1
也就是说,他的开始和结束id按照每页显示数硬算出来的,想要这种方法成立必须满足这样一个条件,即这个论坛只有一个版面,并且id从1开始是连续的,中间不能有间隔,也就是说如果删贴了的话那就会出错。

其次是starleee那个,其实思路是对的,但既然用求首尾id的方法分页,就没有必要用游标,可以利用select top *或set rowcount = 的语法来求出首尾id,第一种方法只能用在sql server里,而后一种在sybase和oracle里都能成立。
starleee提到说试验过这种方法不如用游标快,其实问题出在他的索引建的不好,没有专门为这个存储过程建立索引。影响数据库效率最大的因素就是索引,在这里有必要讲一下。理论上如果一个排序的第一个字段的索引不能过滤掉大部分数据,那么这个索引就是不恰当的,这样将可能有些晦涩,据个例子来说吧:
select id , name , forumid from tablexxx where forumid=1 and name like '%aaa%' order by id
看看上边这条语句,如果想要高效,就需要为它建立这样一个索引:
forumid , id
这样说把,如果在一个有百万条纪录的表中用这条语句,如果不建这个索引,最大的可能是要超时,而建立上述索引,如果有满足条件的纪录的话,那可以在1秒钟内响应(选出第一条符合条件的纪录),而如果没有满足条件的纪录,也可以在一分钟内响应。

下面这个存储过程是我的bbs利用求首尾id的方法分页的,大家可以看一下
/*************************************************************************/
/* */
/* procedure : up_GetTopicList */
/* */
/* Description: 贴子列表 */
/* */
/* Parameters: @a_intForumID : 版面id */
/* @a_intPageNo: 页号 */
/* @a_intPageSize: 每页显示数,以根贴为准 */
/* */
/* Use table: bbs , forum */
/* */
/* Author: bigeagle@163.net */
/* */
/* Date: 2000/2/14 */
/* */
/* History: */
/* */
/*************************************************************************/
if exists(select * from sysobjects where id = object_id('up_GetTopicList'))
drop proc up_GetTopicList
go

create proc up_GetTopicList
@a_intForumID int ,
@a_intPageNo int ,
@a_intPageSize int
as
/*定义局部变量*/
declare @intBeginID int
declare @intEndID int
declare @intRootRecordCount int
declare @intPageCount int
declare @intRowCount int
/*关闭计数*/
set nocount on

/*检测是否有这个版面*/
if not exists(select * from forum where id = @a_intForumID)
return (-1)

/*求总共根贴数*/
select @intRootRecordCount = count(*) from bbs where fatherid=0 and forumid=@a_intForumID
if (@intRootRecordCount = 0) --如果没有贴子,则返回零
return 0

/*判断页数是否正确*/
if (@a_intPageNo - 1) * @a_intPageSize > @intRootRecordCount
return (-1)

/*求开始rootID*/
set @intRowCount = (@a_intPageNo - 1) * @a_intPageSize + 1
/*限制条数*/
set rowcount @intRowCount
select @intBeginID = rootid from bbs where fatherid=0 and forumid=@a_intForumID
order by id desc

/*结束rootID*/
set @intRowCount = @a_intPageNo * @a_intPageSize
/*限制条数*/
set rowcount @intRowCount
select @intEndID = rootid from bbs where fatherid=0 and forumid=@a_intForumID
order by id desc

/*恢复系统变量*/
set rowcount 0
set nocount off

select a.id , a.layer , a.forumid , a.subject , a.faceid , a.hits , a.time , a.UserID , a.fatherid , a.rootid ,
'Bytes' = datalength(a.content) , b.UserName , b.Email , b.HomePage , b.Signature , b.Point
from bbs as a join BBSUser as b on a.UserID = b.ID
where Forumid=@a_intForumID and a.rootid between @intEndID and @intBeginID
order by a.rootid desc , a.ordernum desc
return(@@rowcount)
--select @@rowcount
go

28,406

社区成员

发帖
与我相关
我的任务
社区描述
ASP即Active Server Pages,是Microsoft公司开发的服务器端脚本环境。
社区管理员
  • ASP
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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