【问题标题】:VB.NET multithreading on an Access DatabaseAccess 数据库上的 VB.NET 多线程
【发布时间】:2012-08-08 12:36:59
【问题描述】:

我有一个更新 2,800,000 条记录 Access 数据库的大循环,我将循环划分为 7 个线程,因此每个线程处理 400,000 条记录,循环需要大约 0.7 秒来更新一条记录,因为有很多计算需要完成。

我确信线程将有助于加快进程,因为我在 7200RPM HDD 和 SSD 以及 ramdisk 上测试了应用程序,速度差异并不明显,因此 IO 不是瓶颈。

我希望第一个线程处理前 400k 条记录,第二个线程处理接下来的 400k 条记录,依此类推。

-这样做的正确方法是什么?

-每个线程应该有自己的数据表和绑定源吗?

-当流程完成后,您将如何将结果合并到一个表格中并在 datagridview 中显示?

【问题讨论】:

  • 这是一次性操作吗?如果是这样,为什么还要编写线程方法?如果不是,如果您必须定期更新 280 万条数据库记录,这是否暗示了糟糕的设计?如果不是,也许 Access 一开始就使用了错误的技术?在任何情况下,这个问题都表明与线程访问数据库不同的问题。
  • 手术每3个月做一次
  • 我之前的评论中还有几个问题,愿意回答吗?另外:集合操作(​​UPDATE Table SET Field = CalculatedValue())不可能吗?请注意,您可以在 Access SQL 语句中使用 VBA 中的用户定义函数。进一步:现在需要多长时间?请注意,使用七个线程不会将速度提高七倍。
  • 祝你好运。但在此之前,请尝试让单个 SQL 语句方法发挥作用,看看效果如何。发出 280 万个单独的 UPDATE 语句会损失大量的性能,你不会相信有多少。
  • 真的不知道还能怎么说。所以我再说一遍:1)你真的尝试过让它成为一个集合操作吗?这意味着“影响 280 万条记录的单个 UPDATE 语句”2) 您是否尝试过与 Access 不同的技术? 3) 您是否评估过定期更新这么多记录是否可以避免? 4) 280 万条记录很多。但是22天?很难想象。也许您的计算效率低下?也许您没有设置正确的索引?除了等待 22 天之外,还有这么多种可​​能性。

标签: vb.net multithreading ms-access


【解决方案1】:

Access 数据库只是一个文件。在读写它的时候,你会遇到瓶颈,最重要的是,它很有可能在做这样的事情时被破坏。想象一下对数据的 xml 文件做同样的事情。

一切都取决于您对数据所做的工作。 如果任何键或索引中的任何列都没有更改,并且并非所有记录都会读取/更改。然后一个要读写的线程和一个要处理的池可能会让你到达某个地方。该处理必须足够重要,以使其值得旋转多个线程。因为他们将在磁盘 io 上等待,除非有大量磁盘。 如果您有会更改的索引并且您不必在操作中使用它们。放下它们,处理然后再放回去。

如果您对数据进行重大更改,那么可能

从现有数据库中读取一个线程 然后创建七个(可能需要根据合理的处理器数量进行调整) 只有这个表的空数据库 从父级读取,放入处理器池(如果值得拥有一个),然后写入“七个”副本之一 然后清除原始数据,将其他数据写回(串行并重新组合在一起)

所有所说的放弃访问,请使用完整的 dbms,因为您可能会看到一些您所期望的改进。

并行处理时要记住的一些事情。瓶颈在哪里?在您的情况下,可能是磁盘 IO,多个线程没有解决这个问题,您最终得到了 7 个线程在等待磁盘驱动器。

【讨论】:

  • SQL Server 数据库只是一个文件。这种说法没有任何意义。将 Access 数据库与 XML 文件进行比较也是一个非常大胆的陈述。
  • 对完整 dbms 卷文件的访问由服务器控制,对访问 mdb 的访问(没有双关语)是通过标准操作系统读/写完成的,与 xml 文件甚至文本没有区别文件。就 OP 试图实现的声明而言,这意味着一切。这与结构和复杂性无关,与相当于七个用户读取和写入同一个文件有关。
  • @user1590636 有时,“它不会起作用”是你能得到的最好建议。
  • @Tony 这不是真的。 Access 数据库由 MS Jet 数据库引擎驱动和访问。它支持页面级和记录级锁定以及并发读取器/写入器。不管你信不信,它是一个真正的数据库引擎。与 XML 文件或纯文本的比较存在严重缺陷。
  • @TonyHopkinson 感谢您告诉我要查找的内容。你知道,我以前从未听说过这些事情。您将 Access 数据库与平面文件进行比较仍然是完全错误的,这就是我要指出的。
【解决方案2】:

我建议尝试从另一个角度来解决这个问题。遍历这么多记录并单独更改它们总是很慢。

我建议您尝试发出一次更新许多记录的更新语句,并尝试通过将业务逻辑分解为逻辑语句来封装您的业务逻辑。例如:

UPDATE stock SET retail = 0.95 WHERE retail  < 1.5
UPDATE stock SET retail = 1.95 WHERE retail >= 1.5 and retail < 2.5
UPDATE stock SET retail = 2.95 WHERE retail >= 2.5 and retail < 3.5
UPDATE stock SET retail = 3.95 WHERE retail >= 3.5 and retail < 4.5
UPDATE stock SET retail = 4.95 WHERE retail >= 4.5 and retail < 5.5

如果您可以将业务逻辑分解为单独的语句,您会发现一次更新许多记录的速度要快得多。

如果可以,请发布更多详细信息!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-14
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    相关资源
    最近更新 更多