使用多个线程来更新同一数据库会更快吗?

时间:2020-03-06 14:34:49  来源:igfitidea点击:

我编写了一个Java程序来从MS Access添加和检索数据。目前,它在约3分钟内依次进行了约200K次插入查询,我认为这很慢。我计划使用3-4个线程处理十万条记录的不同部分来重写它。我有一个复合问题:

  • 由于工作负载分散,这是否有助于加快程序运行速度,还是因为线程仍必须顺序访问数据库而使程序运行速度相同?
  • 我们认为采用什么策略可以加快此过程的速度(除了使用Java的prepareStatement进行查询优化外)

解决方案

  • 不知道在不了解瓶颈是什么的情况下,我无法评论它是否会使它更快。如果数据库是限制器,那么更多线程可能会使它变慢。
  • 我将访问数据库转储到平面文件,然后批量加载该文件。批量加载允许的优化远比运行多个插入查询快得多。

在现代的多核计算机上,使用多个线程来填充数据库可能会有所作为。它取决于数据库及其硬件。试试看。

使用MSAccess作为后端数据库,如果我们从MSAccess中进行导入,则可能会获得更好的插入性能。另一个选择(因为我们使用的是Java)是使用Hymaness这样的库直接操作MDB文件(如果我们是从头开始创建的,并且没有其他并发用户的MS Access不能很好地处理它)。

如果这些都不是适合解决方案,那么我建议我们在Java应用程序上使用探查器,看看它是否花了大部分时间在等待数据库(在这种情况下添加线程可能无济于事),或者它正在执行处理和并行化将有所帮助。

只需尝试一下,看看是否有帮助。我猜不会,因为瓶颈可能在于磁盘访问和表锁定,除非我们能找到一种在多个表和/或者磁盘之间分配负载的方法。

刺激批量加载方法可能是我们最好的选择,但一切都值得尝试一次。请注意,瓶颈将成为磁盘IO,并且多个线程可能会使速度变慢。当多个用户敲打文件时,MS访问也可能崩溃,而这恰恰就是多线程方法的行为(进行备份!)。如果性能仍然是一个问题,请考虑升级到SQL Express。

MS Access对SQL Server迁移的文档。

祝你好运。

首先,不要使用Access。将数据移动到其他地方-SQL / Server -MySQL-任何地方。访问内部的DB引擎(称为Jet)太慢了。它不是一个真正的数据库;适用于涉及少量数据的个人项目。它根本无法扩展。

其次,线程很少提供帮助。

JDBC到数据库的连接是整个过程的资源。所有线程共享一个连接。

我们说:"但是等等,我将在每个线程中创建一个唯一的Connection对象。"

高贵,但有时注定要失败。为什么? JVM和数据库之间的操作系统处理可能涉及一个套接字,该套接字是单个进程范围的资源,由所有线程共享。

如果我们在所有线程之间共享一个OS级别的I / O资源,则不会看到太多改进。在这种情况下,ODBC连接是一个瓶颈。 MS-Access是另一个。

我同意,转储Access将是最好的第一步。话说回来...

在.NET和SQL环境中,我肯定已经看到线程有助于最大程度地提高INSERT吞吐量。

我有一个接受异步文件删除然后将它们处理成数据库表的应用程序。

我创建了一个加载器,用于分析文件并将数据放入队列中。队列由一个或者多个线程提供服务,我可以使用一个参数对其进行调整。我发现,即使在具有典型7200RPM驱动器的单核CPU上,理想的工作线程数也为3. 它缩短了加载时间,几乎成比例。关键是要平衡它,以平衡CPU瓶颈和磁盘I / O瓶颈。

因此,在无法选择批量复制的情况下,应考虑使用线程。

由于IIRC访问使用的锁定策略,因此不允许多个连接访问同一文件。

我完全同意转储sql的访问权。