【问题标题】:what's the fastest way to get a large volume of data from an Oracle database into Java objects将大量数据从 Oracle 数据库转换为 Java 对象的最快方法是什么
【发布时间】:2012-03-07 14:30:43
【问题描述】:

将大量数据从 Oracle 数据库转换为 Java 对象的最快方法是什么。

对于数据的组织方式,有什么 Oracle 技巧吗?

我正在考虑使用纯 JDBC 而不是任何 Hibernate 样式库?

让 Oracle 生成一个文件然后从文件中读取会更好吗?尽管这必须以编程方式完成。

感谢所有想法。

【问题讨论】:

  • 我想我会设置一个多线程 JDBC 客户端来读取批量数据。您是要序列化 ​​java 对象还是只是将它们保存在内存中?
  • 我怀疑您是否可以编写一个能够击败 Hibernate 性能的 JDBC 库。确保在您打算访问的所有表上定义适当的索引。
  • @Perception,哇。我们有一个基于 Hibernate 多年的大规模生产服务器产品。最终,可扩展性把我们赶走了。 Hibernate(和任何 JPA)会生成一些非常荒谬的查询。手写 SQL 可以执行好几个数量级。如果您从一个表中插入或检索平面对象,也许 Hibernate 可以(几乎)匹配手写 SQL,但是一旦您将集合放入混合中,就忘了它。对于那些基本上 CRUD 将 ppl 类型输入表单并塞入数据库的应用程序来说,这很好,但不是严肃的数据处理。
  • 我支持“多快?”的问题。多少钱?”。应用程序是否位于同一个盒子上,等等。这个问题需要更多细节才能得到好的答案。
  • @brettw - 我的回答与 OP 的问题一样通用。很明显,您构建实体的方式将对性能产生巨大的影响。大多数嵌套集合的幼稚实现都使用急切获取的 SELECT,而延迟获取的 BATCH 调用或 SUBSELECT 会显着提高性能。

标签: java performance oracle


【解决方案1】:

我不是 Java 或 JDBC 专家,但如果您计划从数据库中提取大量行,您可能会通过增加连接上的预取行来受益。

Connection conn = DriverManager.getConnection ("jdbc:oracle:","user","password"); 

//Set the default row prefetch setting for this connection 
((OracleConnection)conn).setDefaultRowPrefetch(100); 

我相信 JDBC 的默认设置是一次获取一行,因此您需要为获取的每一行支付往返数据库的费用。 (注意,我看到文档建议默认为每次往返 10 行)。将 prefetch 设置为更大的数字将在每次往返数据库时获取更多行。根据行数和网络性能,速度可能会显着提高。

【讨论】:

    【解决方案2】:

    根据您想在这方面走多远,我想放弃 jdbc 并使用 Oracle Call API 和 JNI 编写一个与 DB 驻留在同一台机器上的自定义应用程序,而 JNI 将是最快的......

    使用 JDBC 使用简单的准备好的语句可能要简单得多,然后如果这还不够(并且取决于瓶颈所在的位置),请尝试创建一个存储过程。不过,像 Hibernate 这样的 ORM 所做的缓存不应该被打折,所以我想你必须做一些基准测试。此外,如果瓶颈是数据库并且您编写了一个提高读取性能的存储过程,那么您仍然可以使用 Hibernate 将数据编组为 java 对象。见Using stored procedures for querying

    【讨论】:

    • 您是否有任何证据支持使用 Oracle API 比普通 JDBC 更快的说法?
    • 我对缓存不感兴趣 - 只有;只是将数据放入 Java 内存中。
    • @Emil H,缓存对读取以前从未读取过的数据没有帮助。
    • @Dan 超出了应用程序中的每一层都会降低性能的一般陈述,而不是真的。这就是为什么“我想”这个词含糊不清的原因;)也就是说有一个使用 OCI 的 jdbc 驱动程序(与瘦驱动程序相反),但在最近的版本中,它们与 Oracle 推荐的性能几乎没有差异甚至使用瘦驱动程序...我仍然怀疑直接使用 Oracle Call API 将是最快的方法,但我承认我没有得到支持的数字:/
    【解决方案3】:

    无论你最终做什么,设计/实现“延迟初始化”[真的只适用于复杂的对象层次结构/网络;你说java对象(复数)所以我想象的不仅仅是一个映射到单个对象的单个表]。所以基本上,你只是在读取当时需要的对象;当您运行 getter 方法时,它会针对该数据执行更多 db 调用。

    另一个在 Java 世界中有时被忽视的技巧是:如果您有一些来自代码的复杂 sql,您可以在 Oracle 端创建一个视图,将复杂性嵌入其中,然后将您的对象映射到视图;因此,如果您可以像视图一样展平您的对象,那么您就成功了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多