• 主页
  • Oracle 基础和管理
  • Oracle 高级技术
  • Oracle 认证与考试
  • 职位交流

ORACLE大表扫描操作解决方案

Thumb168 2005-05-23 10:46:16
ORACLE大表扫描操作解决方案
很多朋友在使用ORACLE进行后台数据存储时都可能遇到这样的问题,哪就是,设计的数据库中不可避免的有一两个比较大的数据表,有时可能更多,如果对这些数据表只进行INSERT操作,哪还比较好一些,可是如果要经常进行数据更新(UPDATE)和数据选取(SELECT),在数据量比较少时,程序还能过的去,如果数据量一大,上了百万数量级时,如果数据表设计不合理,执行UPDATE就会出现可怕的现象(一般都遇到过吧)。程序也可能由于对大表的频繁的执行SELECT操作而导致程序和数据库莫明其妙的问题,同时对数据库来说,也是一笔不可呼视的开销。
呵呵,我们公司是做短信业务的(大家过去常说的SP),需要发的下行短信量非常大,经常遇到这样的问题。为了解决此问题,我查阅了一些关于ORACLE的资料,公司用的数据库是ORACLE 8i,发现8I有两个新的特性(大家可能都知道,不过可能没用过),一是8I数据表支持分区功能,二是8I支持JAVA存储过程。本人研究发现,利用这两个特性,转换一下编程模式,解决上面的问题。
8I数据表支持分区功能再结果索引的使用,我就不多说了,好处大家都知道(呵呵,不知道的就去查查资料吧)。在这里,主要说一下我是怎么转换编模式的。过去,我们的程序是这样的,程序为了把要发给手机用户的短信息内容下发给用户(就是通过CMPP协议发到移动的短信中心),程序要频繁的对存放短信息的表进行扫描,导致程序和数据库大量占用CPU,我称这种处理现象为 “主动扫描”,当时想,程序能不能支持“被动扫描”呢,如果没有数据,程序就不去扫描表,有了数据,让数据库告诉程序一下,程序再去数据库中读数据。这样再结合表分区的功能,其不是大大的好啊。可这需要数据库能主动告诉程序有数据 啦。
于是我们想到了JAVA写存储过程,因为JAVA可以与程序进行通讯。
我们的想法是这样的,在前台程序上加一个SOCKET监听端口,用来接听来至数据的命令。在调用向短信息表的过程中调用一下JAVA过程,这样就可以发指令给程序了。程序就知道有数据了。这样就实现的“主动扫描”到“被动扫描”的转换。下面是角本。
JAVA角本。
create or replace and compile java source named logjava as

import java.text.*;
import java.util.TimeZone;
import java.net.*;
import java.io.*;
public class LOGJAVA
{
public static String SendMessage(String CMD)
{
String ResultStr = "OK";
Socket Sock=null;
BufferedWriter os= null;
BufferedReader is=null;
try
{
try
{
Sock = new Socket("192.168.0.51",801); //连接应该程序
Sock.setSoTimeout(1); //设置超时时间
Sock.setTcpNoDelay(true);
os = new BufferedWriter(new OutputStreamWriter(Sock.getOutputStream()));
is = new BufferedReader (new InputStreamReader(Sock.getInputStream()));
os.write(CMD); //发送指令给应用程序。
os.flush();
ResultStr = is.readLine(); //读取返回值。
}
finally
{
os.close();
is.close();
Sock.close();
}
}
catch (Exception e)
{
return e.getMessage();
}
return ResultStr;
}
}

PL/SQL与JAVA转换
create or replace function SendMessage(CMD Varchar2) return varchar2
as language java name 'LOGJAVA.SendMessage(java.lang.String) return java.lang.String';


调用示例:
Pr_insert_SMS(……….)
Res :varcahr2(10);
Begin
Insert tb_sms_out()…………….;

Res := SendMessage(‘NEWDATA’); --告诉程序有数据到来了。

End;

结合8I支持的表分区功能,此解决方案可谓是妙哉啊。。。。
小弟初学,不到之处请提意见。
...全文
88 点赞 收藏 1
写回复
1 条回复
simpleOra 2005年05月23日
回复 点赞
发动态
发帖子
Oracle
创建于2007-09-28

6422

社区成员

5.4w+

社区内容

Oracle开发相关技术讨论
社区公告
暂无公告