【问题标题】:Elegant/efficient way reading millions of records in MySQL Database, Java优雅/高效的方式读取 MySQL 数据库、Java 中的数百万条记录
【发布时间】:2014-03-17 09:14:02
【问题描述】:

我有一个 MySQL 数据库,其中有大约 8.000.000 条记录。因为我需要处理它们,所以我使用 BlockingQueue 作为 Producer 从数据库中读取数据并将 1000 条记录放入队列中。 Consumer 是从队列中获取记录的处理器。

我正在用 Java 编写此代码,但是我一直想弄清楚如何(以一种干净、优雅的方式)从我的数据库中读取数据,并在 BlockingQueue 已满时“暂停”读取。在此之后,控制权将交给消费者,直到 BlockingQueue 中再次有可用的空闲点。从这里开始,生产者应该继续从数据库中读取记录。

保持我的数据库连接打开以使其持续读取是否干净/优雅/高效?或者,一旦控制权从生产者转移到消费者,关闭连接,存储到目前为止读取的记录的 id,然后打开连接并从该 id 开始读取?后者在我看来不是很好,因为我的数据库将不得不打开/关闭很多!但是,我认为前者也没有那么优雅?

【问题讨论】:

  • 在读出记录时,我发现我的记忆力迅速下降!为了阻止这种情况,我需要在我的计算机关闭之前关闭 SQL Server。我已经阅读了一些与此问题类似的帖子(例如,link),但这不起作用。我设置了 FetchSize 但不起作用。

标签: java mysql database-connection blockingqueue


【解决方案1】:

使用持久连接:

  • 您无法有效地构建事务处理
  • 同一连接上不可能有用户会话
  • 应用程序不可扩展。
  • 随着时间的推移,您可能需要对其进行扩展,并且需要管理/跟踪持久连接
  • 如果脚本由于某种原因无法释放表上的锁,那么任何后续脚本都会无限期地阻塞,并且应该重新启动数据库服务器。
  • 使用事务,如果脚本执行在事务块完成之前结束,事务块也将传递到下一个脚本(使用相同的连接)等。

持久连接不会带来非持久连接所能做的任何事情。
那么,为什么要使用它们呢?

唯一可能的原因是性能,当创建到 MySQL 服务器的链接的开销很高时使用它们。这取决于许多因素,例如:

  • 数据库类型
  • MySQL 服务器是否在同一台机器上,如果不是,多远?可能不在您的本地网络/域中?
  • MySQL 所在机器的其他进程过载了多少

总是可以用非持久连接替换持久连接。它可能会改变脚本的性能,但不会改变它的行为!

商业 RDBMS 可能会根据并发打开的连接数获得许可,而持久连接在这里可能会出现错误。

【讨论】:

    【解决方案2】:

    如果您通过在构造函数中传递容量值来使用有界BlockingQueue,则生产者在尝试调用put() 时将阻塞,直到消费者通过调用take() 删除项目。

    这将有助于更多地了解程序何时或如何执行以决定如何处理数据库连接。一些简单的选择是:让生产者和所有消费者获得一个单独的连接,让所有消费者拥有一个连接池,而生产者持有一个连接,或者让所有生产者和消费者使用一个连接池。

    您可以通过使用诸如Spring 之类的东西来管理您的连接池和事务,从而有助于最大限度地减少连接数量;但是,只有在某些执行情况下才有必要。

    【讨论】:

      猜你喜欢
      • 2017-03-15
      • 2012-05-16
      • 1970-01-01
      • 2013-01-06
      • 1970-01-01
      • 2012-02-21
      • 2015-09-04
      • 1970-01-01
      • 2014-05-24
      相关资源
      最近更新 更多