如何解决ORACLE下大批量记录查询时的响应时间问题(利用PRO*C)

hello1998 2002-06-28 10:41:45
背景描述:
有一个日志表,用来存储应用系统中的一些业务操作情况。

table operlog(
name varchar2(16) not null,
cmdcode number(5,0) not null,
result number(5,0) not null,
opertime number(10,0) not null)

该表需要保留一年的日志记录大约为1000~2000万条。因为是要进行打包并网络传输,
所以一次只能返回给客户端100条记录。而且是按照时间的从新到旧的顺序显示,即需要排序。下一次查询时,会把先前的查询条件和前次发送的最后一条记录的 opertime 值再返回给
PRO*C 程序(用来实现操作日志的不同条件查询)。

有两种做法:一种是利用游标存储所有符合条件的记录,在FETCH时只取出前面的100条。
这样做的坏处是当数据记录量特别大时如上百万、上千万条时,会很难处理。

一种是也利用游标,但由ORACLE返回指定行数的记录。
比如,用 select * from operlog where name='test1' and rownum < 101
order by time desc;

但有时发现返回的不符合要求,

大家有没有类似的问题即:
1) 符合查询条件的记录很多,数十万,数百万条,当然有时也会很少。
2) 每次只能返回一小部分,如100条,客户可以继续浏览后在的。
3) 日期要从新到旧。

大家是怎么做的呢?
比如第一种方法,是不是可以通过扩大内存,临时表空间,优化索引等措施达到一定数量级数据记录的可接受的响应速度。
如果采用第二种方法,有没有不用 rownum 的方法。
还有没有其它方案,比如视图。

欢迎大家讨论。
...全文
222 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuxuan 2002-09-01
  • 打赏
  • 举报
回复
数据量大用游标(cursor)会很慢的,不如把数据导出成文本,然后传过去,在导入到数据库,速度可能会快一点。
hello1998 2002-07-12
  • 打赏
  • 举报
回复
TO kevin_76(天马行空):

opertime 本身就是一个 number型的列了,物理存储时应该是按照从小到大的顺序
的。 你说的不是指序列号吧。

你说的‘每次可以取从100*k到100*(K+1)的范围比较简单。’怎么写SQL语句呢?

TO jlandzpa(ORA-00600) :

能多讲讲 /*+first_rows*/ 吗? 它能直接写在SQL 语句中吗?
要不给推荐个这方面的资料吧,

blue__star 2002-07-12
  • 打赏
  • 举报
回复
可以用分区表吧
hello1998 2002-07-12
  • 打赏
  • 举报
回复
我的问题的关键是,有时满足条件的记录可能有三分之一,达数百万条。
但每次只能一百条一百条的传。因为要打包送。

同时要求按时间从近到远的顺序。

我的印象是分区解决的是按某个字段的区间来划分的,不会跨这些区查询的。

是吧
kevin_76 2002-07-07
  • 打赏
  • 举报
回复
我觉得给表增加一个NUMBER类型字段,按时间排序给其按顺序赋值,每次可以取从100*k到100*(K+1)的范围比较简单。
jlandzpa 2002-07-07
  • 打赏
  • 举报
回复
/*+first_rows*/ 是oracle的一种优化策略.
hello1998 2002-07-07
  • 打赏
  • 举报
回复
我是这么解决的:

1、以 那个时间列建联合索引( 时间列为隆序):
create index lognametime on operlog(name, opertime desc);

2 、然后再PRO*C中定义游标时,SQL语句这样写就行了。
select * from operlog where xxx and rownum <= 100;

当然要对同一个查询条件返回下面的记录时,要把上次的最后一条记录的
opertime 值反映到查询语句中,这要用到 动态SQL技术3

敢问一下 biti_rainy(biti_rainy) , 你说的
select /*+first_rows*/ .... from xxx where .... order by ....

中,/*+first_rows*/ 是什么意思,这么写合语法吗?
tianmaa 2002-06-29
  • 打赏
  • 举报
回复
建议:增加一个字段记录时间或顺序,对该字段从大到小建立索引。然后用select ...
速度会很快的。
biti_rainy 2002-06-29
  • 打赏
  • 举报
回复
有足够精力
可是尝试 data buffer 中的 keep buffer and bufer recycle
至于什么shared_pool_size中的缓存,做成存储过程什么的,都是没有太大意义的

biti_rainy 2002-06-29
  • 打赏
  • 举报
回复
select /*+first_rows*/ .... from xxx where .... order by ....

只提供试一下
因你的要求,返回的结果集不是特别大
所以,可能没有太大意义

可能还是要在翻页上下工夫
3yugui 2002-06-29
  • 打赏
  • 举报
回复
DBMS_SHARED_POOL.keeped加载道DBMS_SHARED_POOL
中。
3yugui 2002-06-29
  • 打赏
  • 举报
回复
也可以写一个过程,把数据写到过程里,在吧过程加载到告诉缓冲里
3yugui 2002-06-29
  • 打赏
  • 举报
回复
要用cursor和database pooling 技术
hello1998 2002-06-29
  • 打赏
  • 举报
回复
直接考虑用 opertime 建索引就好了,
只是想知道如何对一个字段从大到小的建立索引。

2,598

社区成员

发帖
与我相关
我的任务
社区描述
Sybase相关技术讨论区
社区管理员
  • Sybase社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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