【问题标题】:Optmize download data from database using java使用java优化从数据库下载数据
【发布时间】:2018-12-31 02:21:39
【问题描述】:

我们正在使用 java 从 oracle/mssql 数据库中下载大约 1000 万条数据。

我们一次获取 5000 条记录,获取 5000 条记录需要 5 分钟,具体取决于位置条件,因此获取和下载 1000 万条记录将需要 (1000 万/5000) *5 分钟,即 10000 分钟。

我们曾尝试一次获取 100000 条记录,但可能会遇到堆空间问题。

有什么办法可以优化吗?

【问题讨论】:

  • fetchSize 设置为较大的值无济于事,反而会消耗更多内存。试试fetchSize = 100。获取数据库中的所有数据需要多少时间?也许问题不在于 Java/JDBC,而在于 SQL 查询本身?如果查询速度很快,也许您可​​以以某种方式将其拆分以将数据提取到多个 Java 线程中
  • 这里的问题是,在每 5000 条记录将 rownum 从 1-5000 和 5000-10000 更改为 1000 万之后,我们一次又一次地执行相同的查询,即使在数据库中,该查询也需要 5 分钟,有没有办法只执行一次查询并从 5000 组中获取所有记录。
  • 使用适用于 JDBC 的 oracle 驱动程序,您只需执行一次查询,然后只需遍历 ResultSet。驱动以fetchSize记录批量加载数据到内存中。
  • 问题是如果我们执行一次查询,那么1000万数据全部加载到结果集中,这将导致堆内存,这就是我们一次获取5k行的原因。
  • 取决于您用于执行查询的内容,但使用普通的旧 JDBC 和 oracle SQL 驱动程序仅将 fetchSize 加载到内存中。当然,如果您不将每条记录都添加到一个巨大的 List 或任何其他集合中

标签: java sql-server database oracle11g oracle10g


【解决方案1】:

您需要确定可以安全返回查询的记录数。您需要查看一条记录的平均大小,即 RecordSize,您需要确定 MaxSize。您可以通过这种方式加载的记录数为

最大尺寸/记录尺寸

但您可能希望加载较少的记录,以避免记录的平均值略大于预期的问题:

0.9 * MaxSize / RecordSize

此外,您需要优化查询以:

  • 不加载不必要的列
  • 使 where、have 和 on 子句更快

您可以将查询分为两步:首先使用真实条件运行查询并仅获取 id,然后仅使用 id 作为条件查询真实列。如果您碰巧使用连接来收集某些列并且在收集 id 时不需要所有连接,这将特别有用。

此外,如果数据库未规范化,您可以通过规范化数据库来改进数据库,并为您正在执行条件的列编制索引。但是,您需要小心索引,因为虽然它会加快读取速度,但会减慢写入速度。

【讨论】:

    猜你喜欢
    • 2023-04-10
    • 2012-12-31
    • 2017-01-06
    • 2011-08-30
    • 2020-11-20
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多