数据量极大时的分页显示问题

ailianhua 2003-11-19 02:36:24
我有个数据表中有20多万条数据

我想分页显示这些数据

每页显示10条

按常规方法做,先从表中读出所有的数据,然后设置分页显示的属性

这样的话,速度会很慢很慢

我想把时间控制在1、2秒种以内

请问各位大哥,有什么好的方法没有

记住是20万条数据,缩短运行时间!!!!

谢谢!
...全文
49 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
wgqql 2003-12-24
  • 打赏
  • 举报
回复
楼上说的这个方法都不错(注均为SQLServer,若为其它数据库请自行更改SQL语句即可):
语句一:
select * from
   (
   select * from (select top 10*4 唯一ID,其他字段 from 表集 where 条件 order by 排序) as a
   union all
   select * from (select top 10*5 唯一ID,其他字段 from 表集 where 条件 order by 排序) as b
   )
   a
   group by 唯一ID,其他字段 having count(唯一ID)=1 order by 排序
但我研究了一下,用这样的语句速度似乎更快一些:

语句二:
SELECT TOP 10 * FROM [表集] where [唯一ID] not in (SELECT TOP 20*5 [唯一ID] FROM [表集] ORDER BY [唯一ID]) ORDER BY [唯一ID]

附上上面两个运行所用的时间:(都是取20000条记录之后的前10条记录)
语句一花了2.567秒
语句二花了0.66秒
我想这样运行效率的差别还是很明显的吧!
有好的算法或者想请记得与我享啊!
:)
超级大笨狼 2003-12-14
  • 打赏
  • 举报
回复

ASP学习史上最强的数据分页方法

  我观前辈的帖子,皆由于数据库的SQL大不一致,且SQL SERVER,ACCESS等菜鸟级数据库没有如rowid,_n_,obs等之类的辅助列,空有BETWEEN运算符而无用武之地,
又无如except之类的数据集运算符,真是令无数英雄尽折腰



  偶详观各数据库SQL,得出是数据库就有取前面N条记录的SQL语法,如什么select top n*****之类的语法,而数据分页的关键问题是取后N条记录的语法偶深思良久,最后小悟,故出此言,还忘前辈们多多指点
  
  取记录集后N条记录的大法:
  
  假设:
  
   1.有一sql语句将产生1000条记录 (select 唯一ID,其他字段 from 表集 where 条件 order by 排序)
   2.每页显示20条记录
   3.当前显示第5页
  
  实现如下:
   select * from
   (
   select * from (select top 20*4 唯一ID,其他字段 from 表集 where 条件 order by 排序) as a
   union all
   select * from (select top 20*5 唯一ID,其他字段 from 表集 where 条件 order by 排序) as b
   )
   a
   group by 唯一ID,其他字段 having count(唯一ID)=1 order by 排序
  
  运行此SQL,至此取记录集后N条记录大法就些完毕
  
  详细说明:
  
  此SQL语句的关键应用技巧在于union all和分组上的条件过滤语句
  
  大家可以根据此技巧完全可以做出一个通用的分页方法,如直接由用户传入sqlstr(sql语句),NumPerPage(每页显示数),currpage(当前页),自己在再函数内组织成通成的SQL分页语句
  
  备注:
  
  当前页为1的话就不需要运行该SQL了,直接TOP一下就OK了
  由于没有环境,该SQL性能无法测试,但相信不会低效
  运行平台在access,sqlserver上都可运行,其它数据库平台只需改top关键字应该就可以就地运行了




topmonkey 2003-11-19
  • 打赏
  • 举报
回复
楼上的办法不好,如果用户表中删除了若干条记录怎么办?
建立索引库。
tuoshi 2003-11-19
  • 打赏
  • 举报
回复
关注!!!
zhgroup 2003-11-19
  • 打赏
  • 举报
回复
我觉得也可以这样:比如说一页显示15条记录,那么第一页就是select top 15,然后,取得第16条记录的ID,和第31条记录的ID,然后将这两个值传入下一页,这样以后页的SQL就是select * from table where id>=16 and id<=31
然后就一直这样传下去。
不知道这个方法怎么样?
DeltaCat 2003-11-19
  • 打赏
  • 举报
回复
声明:上面的例子是 微软的SQL SERVER MVP 写的,不是偶的 ^_^,看一下,也许有帮助
DeltaCat 2003-11-19
  • 打赏
  • 举报
回复
CREATE PROCEDURE spGetNextPage
@id varchar(11) =' 0',
@rows int = 0
AS

SET NOCOUNT ON
SET ROWCOUNT @rows

SELECT
a.au_id,
a.au_fname + ' ' + au_lname AS name
FROM
authors a
WHERE
a.au_id > @id
ORDER BY
a.au_id

SET ROWCOUNT 0
SET NOCOUNT OFF
GO

CREATE PROCEDURE spGetPrevPage
@id varchar(11) =' 0',
@rows int = 0
AS

SET NOCOUNT ON
SET ROWCOUNT @ROWS

SELECT
a.au_id,
a.au_fname + ' ' + au_lname AS name
INTO
#temp
FROM
authors a
WHERE
a.au_id <@id
ORDER BY
a.au_id desc

SET ROWCOUNT 0

SELECT
*
FROM
#temp
ORDER BY
au_id

SET ROWCOUNT 0
SET NOCOUNT OFF


本示例所使用的样本数据来自pubs数据库,您可以对authors 表进行分页。如果想返回第一页的前两行数据,您可以使用带有以下参数的spGetNextPage存储过程: EXEC spGetNextPage @id=' 0', @rows=2

spGetNextPage 过程将返回authors表的前两个作者:

172-32-1176 Johnson White Marjorie Green
如需返回接下来的两个作者,您可以将后一行的ID传递给spGetNextPage:

EXEC spGetNextPage @id='213-46-8915', @rows=2
结果页显示:

238-95-7766 Cheryl Carson Michael O'Leary
如果想移动到先前页面,您可以使用第一行的ID调用spGetPrevPage:

EXEC spGetPrevPage @id='238-95-7766', @rows=2
结果将显示了您在前面看到的第一个页面。使用这种方法的一个缺点是具有唯一ID的列决定了结果集的顺序。在本文的情况下, au_id 字段必须在作者姓名字段的前面。
chang1216 2003-11-19
  • 打赏
  • 举报
回复
给数据库表建立索引 应该会快点!
vivisogood 2003-11-19
  • 打赏
  • 举报
回复
如果有条件的话.给服务器加内存.很有效的!
vivisogood 2003-11-19
  • 打赏
  • 举报
回复
1.要显示的才查询
比如:select 姓名,年龄... from tablename
2.第一页用的是最多了,一定要保证速度
select top 第一页显示的条数 姓名,年龄... from tablename
3.查询条件能缩小范围越多的放到前面
等于一下就把大部分唰掉了
4.如果是联合查询可以用视图加索引(索引用一个或者两个最好了,最要的id做索引)
5.可以考虑用存储过程分页(例子很多的,csdn里面就可以搜索到,要的话也可以贴出来,o不想动不动就贴很长的代码让人很烦的)
kevin_gao 2003-11-19
  • 打赏
  • 举报
回复
这种问题是比较麻烦,我处理的时候就提示用户缩小查询范围。比如记录是按日期的,就让用户缩小日期的范围,总之先查询总记录数,如果超过1万条就罢工,让用户也合作一下,呵呵。
zhaiyf 2003-11-19
  • 打赏
  • 举报
回复
我的意见就是,对于大型数据库不要用select * ,基本上这个问题没什么十全十美的解决办法。要么浪费服务器资源,要么浏览器曼的要死。我是见识过。呵呵,惨就一个字
lovehwq21 2003-11-19
  • 打赏
  • 举报
回复
存储过程其实也差不多,只不过是在后台处理,再回传一个对象集,如果是远端服务器的话肯定是用这种方式,如果是本机,那速度是差不多的
create pro aa(@page int,@size int)
as
declare @size1 int,@size2 int
set @size1=@size*(@page+1)
set @size2=@size*@page
select top @size1 * into #aaa from table
select top @size2 * into #bbb from table
--其中ID是关键字,可以换成你的关键字
select * from #aaa where id not in (select id from #bbb)
ailianhua 2003-11-19
  • 打赏
  • 举报
回复
谢谢各位大哥
我说吗,我记得以前好像是用过rownum的吗
不过,我现在是在sql server数据库下

请问存储过程怎么用啊

xupiao 2003-11-19
  • 打赏
  • 举报
回复
一次只查10條可不可以?
vivisogood 2003-11-19
  • 打赏
  • 举报
回复
数据库服务器加内存,速度提高n倍!!!
lovehwq21 2003-11-19
  • 打赏
  • 举报
回复
楼主,我刚刚也做了个跟你差不多的东西,不过是用ORACLE做的,我提供点思路给你,不过要达到你的要求可能就没有,真要你说的那么快,那只有提高硬件性能!
我用ORACLE,每个表都有个对应的ROWNUM,等于是自增ID,不过,只是加1的,删了记录也是每条加1
然后用这种方法
select aa.*,abcnum from (select *,rownum abcnum from table where rownum<10) aa where abcnum>0
如果是SQL,可以以这样的语法
select * from table where rownum between 0 and 10
不过,SQL没有这么个ROWNUM的东西
所以只能用
m<n,取m和n之间范围的数
select top m from (select top n from table) aa
不要用ORDERY BY,也不要GROUP BY,多增个条件就会慢一点,不过,具体还要看你程序而写
tigerwen01 2003-11-19
  • 打赏
  • 举报
回复
一种方法是提高硬件性能.
Primer2002cn 2003-11-19
  • 打赏
  • 举报
回复
分存储过程分页吧,传个参数进去

28,407

社区成员

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

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