优雅/高效地读取MySQL数据库中的数百万条记录,Java

优雅/高效地读取MySQL数据库中的数百万条记录,Java,java,mysql,database-connection,blockingqueue,Java,Mysql,Database Connection,Blockingqueue,我有一个MySQL数据库,有大约8.000.000条记录。因为我需要处理它们,所以我使用了一个BlockingQueue,作为生产者从数据库中读取数据,并将1000条记录放入一个队列中。使用者是从队列中获取记录的处理器 我是用Java写这篇文章的,但是我一直想弄清楚如何(以一种干净、优雅的方式)读取我的数据库,并在BlockingQueue已满时“暂停”读取。在此之后,控制权将移交给消费者,直到BlockingQueue中再次出现可用的空闲点。从这里开始,制作人应该继续从数据库中读取记录 保持数

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

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


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

具有持久的连接:

  • 您无法有效地构建事务处理
  • 同一连接上不可能的用户会话
  • 这些应用程序是不可伸缩的
  • 随着时间的推移,您可能需要对其进行扩展,并且需要管理/跟踪持久连接
  • 如果由于任何原因,脚本无法释放表上的锁,那么下面的任何脚本都将无限期地阻塞,应该重新启动db服务器
  • 使用事务,如果脚本执行在事务块完成之前结束,则事务块也将传递到下一个脚本(使用相同的连接),等等
持久性连接不会带来任何可以使用非持久性连接进行的操作。
那么,为什么要使用它们呢

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

  • 数据库类型
  • MySQL服务器是否在同一台机器上,如果不是,距离有多远?可能在您的本地网络/域之外
  • MySQL所在的机器被其他进程超载了多少
人们总是可以用非持久性连接替换持久性连接。它可能会更改脚本的性能,但不会更改其行为


商业RDBMS可能通过并发打开连接的数量获得许可,而在这里,持久连接可能会误用。

如果您通过在构造函数中传递容量值来使用有界的
阻塞队列
,然后,生产者将在尝试调用时阻止,直到消费者通过调用删除项目

了解更多有关程序何时执行或如何执行的信息,以决定如何处理数据库连接,这将有助于您做出决定。一些简单的选择是:让生产者和所有消费者获得一个单独的连接,在生产者保持连接的同时为所有消费者提供一个连接池,或者让所有生产者和消费者使用一个连接池


您可以通过使用
Spring
等工具来管理连接池和事务,从而最大限度地减少连接数量;但是,只有在某些执行情况下才有必要这样做。

当读取记录时,我看到我的内存迅速减少!要停止此操作,我需要在计算机关闭之前关闭SQL Server。我读过一些关于这个问题的类似帖子(例如),但是这不起作用。我已经设置了FetchSize,但不起作用。