【问题标题】:how to increase the performance of the java application fetching a large data from oracle database?如何提高从 oracle 数据库中获取大数据的 java 应用程序的性能?
【发布时间】:2010-12-05 01:28:35
【问题描述】:

我有 3 个数据库表 - 项目、审计和评论。我必须从 Items 表中获取大量数据,比如 100 万条记录,并且对于获取的每个项目,我必须从 Audits 中检索数据评论并将报告写入分隔文件。所以输出可能看起来像,

Item entry 1
    Audit entry 1 for Item 1
    Audit entry 2 for Item 1
    Audit entry 3 for Item 1
    Comment entry 1 for Item 1
    Comment entry 2 for Item 1
Item entry 2 
    Audit entry 1 for Item 2
    .
    .
    .

现在这要花很多时间,因为程序要为每个 item 查询 oracle 100 万次。我想通过线程提高性能,但我不熟悉线程。那么有人可以帮助我提高性能吗?

【问题讨论】:

  • 请包括您当前使用的算法和查询。

标签: java multithreading performance oracle


【解决方案1】:

您可以检索项目,一个联合查询来获取审计,另一个获取评论。

加快查询结果的一种方法是将选择行作为单个连接字符串返回,然后自己拆分该行。这用于将检索速度提高 2-3 倍。较新版本的 Oracle 在这方面可能更智能并且开销更少。

但是,无论如何,您可能需要一段时间才能从 Oracle 获取大量数据。

【讨论】:

  • 彼得,很酷的人... Concat 是一个好主意.. 这肯定会加快速度。我会用这个告诉你增加系数。
【解决方案2】:

阅读此资源:http://www.w3schools.com/Sql/sql_join.asp 并使用 join。

【讨论】:

  • 没有。我不能使用连接。如您所见,我需要以 3 种不同类型的行给出输出。第一行应包含 item 表中的记录以及 auditcomment 表中的下一组行
  • 要让连接起作用,您需要执行三个查询。 (而不是在单个连接中做所有事情)您可以对审计表执行查询,获取与项目表的键匹配的所有记录,然后在内存中执行匹配。
【解决方案3】:

您可以编写一个存储过程,该过程将使用 utl_file 包输出文件,然后从 java.util 中调用它。这样你就可以使用类似的东西

f := utl_file.fopen('my_dir','my_file','w');
FOR r_items IN (SELECT * FROM items) LOOP
  utl_file.put_line(f,r_items.name);

  FOR r_audit IN (SELECT * FROM audit WHERE item_id = r_items.id) LOOP
    utl_file.put_line(f,r_audit.some_field);
  END LOOP;

  FOR r_comments IN (SELECT * FROM comments WHERE item_id = r_items.id) LOOP
    utl_file.put_line(f,r_comments.some_field);
  END LOOP;
END LOOP;

【讨论】:

    【解决方案4】:

    根据您提供的有限信息,不清楚您在做什么,真正的问题是什么。

    • 如果您正在执行一百万个单独(小)查询,则应考虑重组应用程序,以便将它们成批组合,或对整个表执行 SELECT。

    • 如果问题是在单个查询中获取一百万行,那么可以考虑使用更复杂的查询,或者存储查询,或者在数据库端做一些数据缩减。

      李>

    【讨论】:

      【解决方案5】:

      可能最好将 UNION 与 JOIN 结合起来以最佳方式获取所有数据。 查询可能如下所示:

      select itm.itemid
      ,      tmp.what || ' ' || tmp.entry || ' for Item ' || tmp.itemid line
      from   items itm
      join
      (
          select itemid
          ,      entry 
          ,      'Audit' what
          from   audits
          union all
          select itemid
          ,      entry 
          ,      'Comment' what
          from   comments
      ) tmp on itm.itemid = tmp.itemid
      

      【讨论】:

        【解决方案6】:

        我的想法是运行三个查询(一个返回所有项目,一个用于所有 cmets,一个用于所有审计条目)每个按项目 id 排序

        SELECT * FROM
          (SELECT itemid, 1 type, null seq, item_line line
           from items
           union all
           select itemid, 2, audit_seq, audit_line
           from audit
           union all
           select itemid, 3, comment_seq comment_line 
           from comments)
        order by itemid, type, seq
        

        这意味着将构建行条目的所有逻辑都放入数据库中,但它可能会比 java 代码运行得快很多。

        【讨论】:

          【解决方案7】:

          按照 BazzPsychoNut 所说的那样管理 UNION/JOIN 后,如果 ResultSet 很大,将 FetchSize 值调整为更大的值可能会有所帮助。 Oracle 的默认值为 10。

          Statement stmt = conn.createStatement();
          stmt.setFetchSize(200);
          ResultSet rset = stmt.executeQuery(sql);
          

          Retrieve large ResultSet

          【讨论】:

            【解决方案8】:

            如果您的系统(硬件、配置等)的大小可以处理您放入其中的数据量,那么最好、最快和最简单的方法是简单地将表连接到一个查询中,获取行(参见其他 cmets 关于fetch_size),然后以你想要的任何格式转储它。

            从示例输出格式来看,您需要按排序顺序(item、audit、cmets)处理行。您将遍历行并跟踪最后处理的项目,并且只要当前的 ITEM_ID 与之前的不同,您就输出项目数据。

            当您决定如何实现此功能时,您需要考虑的一个最重要的方面是连接和排序是否适合内存。如果排序/连接溢出到磁盘,您将不得不解决该问题以实现所需的性能。有关如何避免磁盘溢出的一些示例:

            在 ITEM_ID 上对表(或它们的副本)进行哈希分区。然后,您可以分区连接表,以便每个连接都适合内存。

            或者您可以从所有表中获取所有数据,并在您的 java 代码中,将项目放在一个链表中,并将审计/cmets 放在一些由 item_no 键入的基于哈希的结构中。然后,您将遍历项目并通过 item_id 查询 audit/cmets。此解决方案避免了排序操作,并且不需要将连接的结果放入内存中。

            或者您可以实现一些自己动手的分区。例如,查询数据 9 次。在第一个查询中,您只获取 ITEM_ID 以 1 开头或结尾的项目。第二个查询获取所有以 2 等开头/结尾的项目。该解决方案导致对所有表进行 9 次表扫描,这显然不是很有效。但如果你能避免溢出到磁盘,它实际上可能会更快。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-05-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-01-01
              相关资源
              最近更新 更多