Bo *_* Ye 2 java mysql oracle multithreading locking
让我们想象一个环境:有一个数据库客户端和一个数据库服务器。数据库客户端可以是Java程序或其他程序等;数据库服务器可以是mysql、oracle等。
需求是将大量记录插入到数据库服务器上的一张表中。
最简单的方法是建立一个循环,客户端每次在其中插入一条记录,直到插入所有记录为止。这是单线程顺序插入。
还有另一种多线程并发插入方式,可以让客户端同时启动多个线程,每个线程将一条记录插入表中。直观上,因为这些记录是独立的,并且假设现代数据库服务器配备了 RAID,其中并发 IO 得到了很好的支持,它们似乎能够获得多次插入的实际和真正的并发性,因此,这种方式可以改进性能,与上述方法相比。
然而,当我深入了解更多细节后,我发现情况可能并非如此。此链接 -- Multi threaded insert using ORM? 表示在同一个表上的插入需要对整个表上的每次写入进行锁定。因此,每次插入都会阻塞后面的另一个插入,最终,这种方式只是另一种顺序多次插入,根本没有任何性能提升。
我的问题如下:
尽管处理大量插入的最佳方法似乎是启用批量插入,但我仍然很好奇在插入时锁定整个表的理由。
提前致谢!
=================================================== ===================
经过大量的阅读和研究,结果表明我的问题实际上是错误的。真正的事情是一个插入不会同时阻止另一个插入。(至少对于 Oracle 来说是这样)。
这个答案需要对数据库的理解,这超出了这里简单答案的范围。既然你问的是Oracle:
Oracle 并不像您想象的那样锁定整个表。在插入期间,本质上是表结构上有一个锁(即,因此某人不能在插入过程中删除列),但在数据级别,没有锁。这意味着您可以在单个表上进行许多并发插入。更新(在 Oracle 中)类似。然而,在这种情况下,正在更新的数据上存在行锁。所以你可以在同一张表上进行许多并发更新;但不在同一行。
话虽如此,多线程插入并不是加载大量数据的方式。为此,Oracle提供了一种替代方法,即直接路径加载。在这种方法中,我们加载行集,而不是逐行(慢慢地)加载。并不是单次插入慢;而是单次插入慢。恰恰相反,它们速度非常快。但即使每次插入 0.1 毫秒,当您必须加载 100M 行时,也需要 2.7 小时!由于基于集合的方法允许数据库执行并行性,而不是手动“自行开发”的多线程方法因此,为了让您了解可以做什么,我刚刚加载了大约 60 亿行(大约 1 TB 数据)约10分钟 最后,数据加载通常受 CPU 限制;不受 IO 限制。
| 归档时间: |
|
| 查看次数: |
4803 次 |
| 最近记录: |