我编写了一个Java程序来添加和检索MS Access中的数据。目前它在~3分钟内顺序通过~200K插入查询,我认为这很慢。我计划使用3-4线程处理数十万条记录中不同部分的线程来重写它。我有一个复合问题:
由于工作量分散,这有助于加速程序,还是会相同,因为线程仍然需要按顺序访问数据库?
您认为哪种策略可以加快此过程(除了使用Java的preparedStatement之外我已经做过的查询优化除外)
答案 0 :(得分:3)
不知道。如果不知道更多关于瓶颈的信息,我就无法评论它是否能让它变得更快。如果数据库是限制器,那么更多线程可能会减慢速度。
我会将访问数据库转储到平面文件,然后批量加载该文件。批量加载允许进行优化,这比运行多个插入查询要快得多。
答案 1 :(得分:2)
首先,不要使用Access。将数据移动到其他任何地方 - SQL / Server - MySQL - 任何东西。访问中的数据库引擎(称为Jet)可怜的慢。它不是一个真正的数据库;这是涉及少量数据的个人项目。它完全没有扩展。
其次,线程很少有帮助。
JDBC-to-Database连接是一个进程范围的资源。所有线程共享一个连接。
“但是等等,”你说,“我将在每个线程中创建一个唯一的Connection对象。”
高贵,但有时注定要失败。为什么? JVM和数据库之间的操作系统处理可能涉及一个套接字,它是一个单一的进程范围的资源,由所有线程共享。
如果您有一个在所有线程中共享的单个操作系统级I / O资源,您将看不到太多改进。在这种情况下,ODBC连接是一个瓶颈。而MS-Access是另一个。
答案 2 :(得分:1)
使用MSAccess作为后端数据库,如果从MSAccess中导入,则可能会获得更好的插入性能。另一个选择(因为你正在使用Java)是直接操作MDB文件(如果你是从头开始创建它,并且没有其他并发用户 - MS Access不能很好地处理它)与像{{{ 3}}
如果这些都不是您的解决方案,那么我建议您在Java应用程序上使用分析器,看看它是否花费大部分时间等待数据库(在这种情况下,添加线程可能无济于事)或者如果它正在进行处理和并行化将有所帮助。
答案 3 :(得分:1)
刺激批量加载方法可能是你最好的选择,但一切都值得尝试一次。请注意,您的瓶颈将是磁盘IO,多个线程可能会减慢速度。当多个用户正在敲击文件时,MS访问也会崩溃,而这正是您的多线程方法的作用(进行备份!)。如果性能仍然是一个问题,请考虑升级到SQL express。
祝你好运。答案 4 :(得分:1)
我同意倾销Access是最好的第一步。说完了......
在.NET和SQL环境中,我确实看到线程有助于最大化INSERT吞吐量。
我有一个接受异步文件丢弃的应用程序,然后将它们处理成数据库中的表。
我创建了一个解析文件并将数据放入队列的加载器。队列由一个或多个线程提供服务,其最大值我可以使用参数进行调整。我发现即使在具有典型7200RPM驱动器的单核CPU上,理想的工作线程数也是3.它将加载时间缩短了几乎成比例。关键是要平衡它,以便平衡CPU瓶颈和磁盘I / O瓶颈。
因此,如果批量复制不是一种选择,则应考虑线程。
答案 5 :(得分:0)
在现代多核机器上,使用多个线程来填充数据库可能会有所不同。这取决于数据库及其硬件。试试吧,看看。
答案 6 :(得分:0)
试一试,看看是否有帮助。我猜不是因为瓶颈很可能是在磁盘访问和锁定表中,除非你能找到一种方法将负载分成多个表和/或磁盘。
答案 7 :(得分:0)
由于其使用的锁定策略,IIRC访问不允许多个连接到同一个文件。
我完全赞同转储sql的访问权限。