优雅/高效的方式读取MySQL数据库中的数百万条记录

时间:2014-03-17 09:14:03

标签: java mysql database-connection blockingqueue

我有一个包含~8.000.000记录的MySQL数据库。由于我需要处理它们,所以我使用BlockingQueue,当生产者从数据库中读取并将1000条记录放入队列时。 Consumer是从队列中获取记录的处理器。

我用Java写这篇文章,但是我一直想弄清楚如何(以干净,优雅的方式)从我的数据库中读取并暂停' BlockingQueue已满时读取。在此之后,控制权将交给消费者,直到BlockingQueue中再次有可用的免费点。从这里开始,Producer应该继续从数据库中读取记录。

是否干净/优雅/高效保持我的数据库连接打开以便连续读取?或者,一旦控件从Producer转移到Consumer,关闭连接,存储到目前为止读取的记录的id,然后打开连接并开始读取该ID?后者在我看来并不是很好,因为我的数据库必须打开/关闭很多!但是,在我看来,前者也不是那么优雅?

2 个答案:

答案 0 :(得分:1)

持久连接:

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

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

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

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

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

商业RDBMS可能会通过并发打开的连接数来获得许可,这里持久连接可能会错误地服务。

答案 1 :(得分:0)

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

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

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