如何从数据库中高效的取出需要的记录?

DongXY 2002-07-10 03:48:09
比如有一个表
Create table Test(
nID integer primary key,
sName varchar(20),
sAddress varchar(200)
);
表中有20万条记录。在客户程序中查询显示时按20条分页显示。其中,sName、sAddress
可以重复。按任意字段排序,如何高效的取出我要的那20条?
我试过的方法:
1、用ADO读记录,用PageSize属性设置分页大小,然后根据页号取得数据。
但是这样做,是把数据全部读出,然后分页。这样我需要的数据只占读出的数据的万分之一。效率很低。
2、用存储过程。创建一个临时表,将记录按我需要的顺序存入。然后取得我需要的数据。
这样做也很低效。
3、用存储过程。定义一个游标,从游标中取出需要的数据。性能仍不能让人满意。

注意,能按任意字段排序。比如按sName排序。选出大于'张三'的记录。
select * from Test where sName > '张三'
由于名子可重复,所以用Top 20 无法取出我要的数据。
...全文
59 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
DongXY 2002-07-17
  • 打赏
  • 举报
回复
我认为没有比临时表更好的办法。如果依次读取很多的数据,那么内存就会成为瓶颈,通过网络传输数据也成问题。解决办法是每次查询时加条件,使结果集不要太大。
好了,给分。
leimin 2002-07-11
  • 打赏
  • 举报
回复
你有过多重复的字段,证明你的DATABASE的设计有待改进,
关于快速查询:字符的字段的查询一定比INT的要慢,所以将表的结构改小,在要查询的主表已INT字段为主,字符字段记录在另一表中,这样在一个页下可以保存更多的记录,再加上合理的INDEX,查询的效率会提高.
EXAMPLE:select * from Test where sName > '张三'改为
select * from test left join test2 on test.id=test2.id where sname_id >10002
DongXY 2002-07-11
  • 打赏
  • 举报
回复
大家帮忙想想办法。
firedragoninhell 2002-07-11
  • 打赏
  • 举报
回复
可以这样试一下:
再建一个索引 (sName,sAddress),应该会快些。
DongXY 2002-07-11
  • 打赏
  • 举报
回复
TO: j9988(j9988)
你的方法正是我说的第二种方法。当数据量很大,比如取名张三的有10万,取名李
四的有10万。现在按名字升序排列,则李四在前,张三在后(它们的nID是不定的
的,1可能是张三,2可能是李四)。现在我要取第21至第40条的记录,就不得不把
全部的数据放到临时表中,这样会占用大量的内存,处理速度也很慢。
另外,我试了这样的例子:数据库有20万条记录。按nID排序(或是一个不允许
重复的字段),每次取20条,用如下的SQL:
select top 20 * from test where nID > <条件值>
响应时间在一秒之内。现在我想,如实在不行,则不允许按可重复字段排序。
leimin 2002-07-11
  • 打赏
  • 举报
回复
表的设计是没问题。我想将Primary key 改为sName,会提高查询的性能,不过写入的性能会降低。(对你的要求会比较合适)
你还可以建立VIEW,根据SNAME的开始字母,在VIEW上再建立INDEX(ONLY SQLSERVER 2K)性能会有很大的提高,试试看吧!
bluelark 2002-07-11
  • 打赏
  • 举报
回复
学习
DongXY 2002-07-11
  • 打赏
  • 举报
回复
TO: leimin(leimin)
表的设计问题不大。比如记录企业的信息表:
Create Person(
nID int not null, /*编号*/
sName varchar(10) not null, /*企业名称,不重复*/
nCityID int not null, /*所在城市编号*/
Primary key (nID),
Foreign key (nCityID) References ...
)
城市用另一个表存储。比如北京市的人有10万。现在要取出按城市排序的记录集中
的第20至40条。
warp1977 2002-07-11
  • 打赏
  • 举报
回复
关于你的名称重复的时候不能取出二十个姓名的问题。你可以加一个参数with ties ,如:select top * with ties from test Order BY Sname 就可以不理会相关的值。
再者,从现在来说,使用临时表来分页处理是目前最好的方式,现在涉及到还要对按条件检索后的数据进行分页的问题,而且就算你使用别的方式,也可能在后台SQLSERVER也是使用临时表在处理,只是在程序中看不到罢了。你也可以这样处理:不按条检索可以使用ID》20的方式。使用按条件检索的数据使用临时表的方式。我想这样是效率最高。
cxmcxm 2002-07-10
  • 打赏
  • 举报
回复
未完全理解你的意思,是否取出20条已知nID的记录
zhxfzhxf1 2002-07-10
  • 打赏
  • 举报
回复
UP
guguda 2002-07-10
  • 打赏
  • 举报
回复
up
xhfjy 2002-07-10
  • 打赏
  • 举报
回复
同意楼上的方法,
请贴主把自己写的存储过程贴出来分析分析
j9988 2002-07-10
  • 打赏
  • 举报
回复
用存储过程。创建一个临时表,将记录按我需要的顺序存入。然后取得我需要的数据。
加上一字段,identity(int,1,1) as tempid

然后如取21~40的记录:select * from tempid where tempid>20 and tempid<40

仅是建议而已!
DongXY 2002-07-10
  • 打赏
  • 举报
回复
help me !

34,587

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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