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

lam*_*988 6 java database oracle

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

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

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

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

1.使用准备好的陈述.使用参数化SQL

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

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

当然,已经使用过.

3.使用连接池.

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

4.尝试组合查询和批量更新.

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

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

当然.

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

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

7.关闭自动提交

已经做到了.

期待任何帮助.

Ton*_*ews 10

4.尝试组合查询和批量更新.

不能这样做.每个查询/插入/更新都取决于数据库的信息.例如,我们在DB中查找客户端的信息,如果我们找不到他的用法,我们会将用法插入到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;
Run Code Online (Sandbox Code Playgroud)

这意味着对数据库进行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)';
Run Code Online (Sandbox Code Playgroud)

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

2)使用存储过程:

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

存储过程在名为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;
Run Code Online (Sandbox Code Playgroud)


Eri*_*ler 6

检查你的索引!更新性能不佳可能是外键约束的结果,其中外键上的索引在引用表上缺失.

4)尝试组合查询和批量更新.

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

我想到了两件事:

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

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

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

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


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


Gar*_*owe 4

获取一份《专业 Oracle 编程》的副本。

2005 年看起来有点老了,但 Oracle 在优化性能方面并没有发生太大变化。我自己也有这本书,并使用它的建议来加速许多应用程序看似棘手的性能问题。得到它。阅读。做吧。

那么等待快递的时候可以做什么呢?

  • 让 DBA 站在您这边,您需要他们的帮助和工具
  • 如有必要,获取 TOAD 并支付额外的查询分析工具费用
  • 检查您运行的每个查询的索引 - 您需要仔细检查执行计划(AUTOTRACE 和 EXPLAIN PLAN 是您的朋友)
  • 考虑您正在使用的索引类型(功能索引可以解决问题吗?)
  • 考虑使用可传输表空间
  • 使用内置优化器收集信息
  • 获取统计数据,以便您可以衡量性能提升(无论预缓存等)
  • 考虑存储的轮廓
  • 考虑物化视图以允许将数据拆分为立即需要的数据和可能延迟的数据
  • 考虑表截断以减少整个表的大小,因为较旧的数据被分出

这应该足以让您牢牢掌握失败的原因以及如何解决它。