如何更快地通过Java进行Oracle更新/插入操作?

时间:2011-02-02 03:22:05

标签: java database oracle

我在公司遇到的问题是 - 我们的程序速度不够快。更具体地说,我们是电信公司,这个程序处理我们城市每个手机用户的电话/互联网服务交易。由于iphone用户下载内容的数量太多,我们的程序无法足够快地处理它们。

情况是,用户进行的交易金额是我们程序处理的交易的两倍。程序的大部分运行时间都由数据库事务控制。

我通过互联网搜索并浏览了一些网站(例如:http://www.javaperformancetuning.com/tips/rawtips.shtml),讨论了数据库中的Java性能,但我找不到适合我们的建议。

这些建议不适用/已经使用过,例如:

1。使用预备陈述。使用参数化SQL

已经使用过准备好的声明。每次都会通过清除参数和设置参数使用不同的参数。

2。调整SQL以最小化返回的数据(例如,不是'SELECT *')。

当然,已经使用过了。

第3。使用连接池。

我们在程序执行期间保持一个连接。我怀疑汇集无法解决问题,因为我们的程序充当1个用户,因此并发访问DB没有问题。如果你们有人认为合并是好的,请告诉我原因。感谢。

4。尝试将查询和批量更新结合起来。

不能这样做。每个查询/插入/更新都取决于数据库的信息。例如,我们在DB中查找客户端的信息,如果我们找不到他的用法,我们会将用法插入到DB中,否则我们会更新。

5。完成后关闭资源(连接,语句,结果集)

不确定

6。选择最快的JDBC驱动程序。

我不知道。我在互联网上搜索可用的驱动程序类型,我很困惑。我们使用oracle.jdbc.driver.OracleDriver,我们使用thin而不是oci,这就是我所知道的。另外,我们的程序是两层方式(java< - > oracle)

7。关闭自动提交

已经完成了。

期待任何帮助。

7 个答案:

答案 0 :(得分:10)

  

<强> 4。尝试将查询和批量更新结合起来。

     

不能这样做。一切   查询/插入/更新取决于   数据库的信息。例如,   我们查找客户端的数据库   信息,如果我们找不到他的   用法,我们将用法插入DB,   否则我们会更新。

如果您是从Java应用程序执行此操作,则可以通过一次往返在数据库中执行此操作来提高性能。有几种方法:

1)使用SQL MERGE语句

2)编写存储过程来执行插入或更新逻辑,然后从Java调用它。

进一步说明

我假设从你所说的那一刻起你的Java逻辑就像这样:

// Pseudocode
execute SQL 'select count(*) from mytable where id=?'
if result = 0 then
    execute SQL 'insert into mytable (id,a,b,c) values (?,?,?,?)';
else
    execute SQL 'update mytable set a=?, b=?, c=? where id=?';
end if;

这意味着2次单独往返数据库:一次检查记录是否存在,另一次是根据需要插入或更新。

替代方案是:

1)使用SQL MERGE语句:

// Pseudocode
execute SQL 'merge into mytable t using (select ? id, ? a, ? b, ? c from dual) s
             on (t.id = s.id)
             when matched then update set t.a = s.a, t.b = s.b, t.c = s.c
             when not matched then insert (id, a, b, c)
                  values (s.id, s.a, s.b, s.c)';

MERGE语句起初有点令人生畏,特别是在这样的情况下你必须使用Oracle的“双”表。

2)使用存储过程:

// Pseudocode
execute SQL 'begin mytable_package.insert_or_update
              (p_id => ?, p_a => ?, p_b => ?, p_c => ?); end;'

存储过程在名为mytable_package的包中看起来像

procedure insert_or_update (p_id mytable.id%type
                           ,p_a  mytable.a%type
                           ,p_b  mytable.a%type
                           ,p_c  mytable.a%type
                           )
is
begin
    update mytable
    set    a = p_a, b = p_b, c = p_c
    where  id = p_id;
    if sql%rowcount = 0 then
        insert into mytable (id, a, b, c) values (p_id, p_a, p_b, p_c);
    end if;
end;

答案 1 :(得分:6)

检查索引!!! 错误的更新性能可能是外键约束的结果,其中外键上的索引在引用表上缺失。

  

4)尝试组合查询和批处理   更新。

     

不能这样做。一切   查询/插入/更新取决于   数据库的信息。例如,   我们查找客户端的数据库   信息,如果我们找不到他的   用法,我们将用法插入DB,   否则我们会更新。

我想到了两件事:

  • 执行UPDATE语句并检查ExecuteUpdate()的结果;仅当它为零时,执行INSERT。为您保存一个SELECT语句。

  • 始终(可能批量)插入中间表,稍后使用MERGE语句更新您的使用表。

  

5)完成后关闭资源(Connections,Statements,ResultSet)

尽可能长时间保持连接打开(即永久关闭服务器),准备一次PreparedStatement并重复使用。


在写入数据库之前进行一些聚合。现在生成交易的手机用户可能会在几秒钟内生成另一个交易。使用哈希表来聚合当前使用情况,并在一分钟左右后将其写入数据库。

答案 2 :(得分:4)

获取Professional Oracle Programming

的副本

2005年似乎有点偏旧,但在优化性能方面,Oracle并没有大幅改变。我自己有这本书,并且已经使用它的建议来加速许多应用程序看似棘手的性能问题。得到它。阅读。做吧。

那么您在等待快递时可以做些什么?

  • 让DBA站在您一边, - 您需要他们的帮助和工具
  • 抓住TOAD并在必要时支付额外的查询分析工具
  • 检查您运行的每个查询的索引 - 您需要仔细检查执行计划(AUTOTRACE和EXPLAIN PLAN是您的朋友)
  • 考虑一下你正在使用的索引类型(功能索引能做到这一点吗?)
  • 考虑使用可传输的表空间
  • 使用内置优化工具收集信息
  • 获取统计信息,以便衡量性能提升(无论预缓存等)
  • 考虑stored outlines
  • 考虑物化视图以允许将数据拆分为立即需要的数据以及可能会延迟的数据
  • 考虑使用表截断来减少整个表的大小,因为旧的数据已经完成了

这应该足以让你牢牢掌握失败的原因以及解决方法。

答案 3 :(得分:3)

首先你需要DBA在你身边来告诉你实际花费的时间。您可以在客户端快速闪电,并且在设置关键索引之前仍然需要很长的事务处理时间。

我使用Java + Oracle已经八年了,但我没有找到oci驱动程序(在DLL中使用本机驱动程序)比使用瘦驱动程序(所有用Java编写)快得多。

快速解决这个问题,可以生成一个1000或10000个事务的文本文件,让“SQLLDR”将批处理注入数据库。也许更多。正确调用SQLLDR是最快的事情,它会让你有时间正确地执行它。

答案 4 :(得分:0)

您是否为每次执行启动JVM的新实例?您能否详细说明应用程序的性质(即如何调用它,触发调用的内容等)。根据您的描述,它听起来并不像Java和DB问题。听起来好像是某种数据库索引问题或其他设计问题。您正在使用的SQL命令的性质是什么?您是否计划或分析了这些电话,看看是否有些电话比其他电话要长?

答案 5 :(得分:0)

您可以将工作负载划分为使用多个会话到数据库吗?有很多往返数据库的往返导致延迟。如果表的结构正确,它们可以毫无问题地处理多个并发插入/更新(检查重插入表的INITRANS属性是否与执行插入的并发会话数相同)。我认为这将是赢得应用性能最简单的方法。 正在使用哪个版本的数据库? 你能得到ADDM报告吗?他们可以立即告诉您 - 数据库中的问题是什么 - 如果有的话。 应用服务器有足够的CPU资源吗?如果没有,这是将负载分成多个会话的另一个原因,在这种情况下分成多个应用服务器。 如果没有statspack报告或 - 最好是 - ADDM报告,很难说出问题所在。

我希望这有帮助, 罗纳德。

答案 6 :(得分:0)

如果您希望将DBA的参与保持在最低限度,您至少可以要求登录以访问在测试服务器上运行的Oracle Enterprise Manager。在OEM中,您实际上可以看到哪些操作需要很长时间。 OEM还会尝试通过建议提高性能的方法来帮助您,例如添加索引或更改查询结构。希望OEM至少能为您提供可靠的理由,要求DBA进一步参与。