【发布时间】:2016-07-02 14:49:38
【问题描述】:
我正在用 java 编写一个函数来生成并使用休眠模式保存一个唯一代码,然后在 get 请求中发送它,我将不得不在一次调用中执行此操作 30,000 次。
即使我无法将 HttpRequest 与休眠插入分开,多线程是否会帮助我加快速度?
【问题讨论】:
标签: java multithreading hibernate httprequest
我正在用 java 编写一个函数来生成并使用休眠模式保存一个唯一代码,然后在 get 请求中发送它,我将不得不在一次调用中执行此操作 30,000 次。
即使我无法将 HttpRequest 与休眠插入分开,多线程是否会帮助我加快速度?
【问题讨论】:
标签: java multithreading hibernate httprequest
我猜您愿意尽可能快地进行 30 000 次插入。您可以从 100 个线程开始,然后从这些线程执行 3000 次插入 - 但是对于每个线程,您需要一个专用的数据库会话(数据库连接) - 否则您不会获得任何性能优势。
考虑整个链的并发
线程与否?实际上,这取决于您的数据库。
例如,Oracle 允许您从多个会话中执行插入操作https://dba.stackexchange.com/questions/16131/how-does-oracle-handle-multiple-concurrent-inserts-against-one-table 这意味着您的线程可以一起工作以尽可能快地发送数据。降低提交率是个好主意,并且为了提高速度,仅在 100-1000 次插入后才提交事务。
然而,在 MS SQL https://social.msdn.microsoft.com/Forums/sqlserver/en-US/db00512d-0dc5-4bae-9ea4-7d6726d2d731/inserting-into-a-single-heap-table-from-multiple-sessions?forum=sqldatabaseengine 上事情并不那么容易,并且有锁定整个表的 SQL 引擎,所以实际上您的插入将完全串行执行。
多少线程?
这又取决于您的数据库。在生产 Oracle 安装中,每个应用程序打开不超过 20-100 个会话是个好主意,因此您不应尝试创建 1000 个线程。简单地保持 1000 个数据库连接会损害数据库服务器,可能还会损害您的应用程序。
优化往返
您会注意到插入时间大部分浪费在单个调用上。 IE。 30 000 次插入是到数据库服务器的 30 000 次往返。这需要大量时间。不幸的是,Hibernate 在这方面也非常低效,所以你不能做太多。
一个好的解决方案是使用 JDBC 批处理模式,它与 Oracle 配合得非常好(与插入相比提供 10-100 倍的改进),请参阅 http://viralpatel.net/blogs/batch-insert-in-java-jdbc/
想想你的问题
我确信通过一次操作插入 30 000 个东西是个坏主意 :) 与其提高插入速度,不如想想为什么你需要插入 30 000 个东西?您是否逐字节插入图片?
【讨论】:
identity 类型的 id 生成器,是的,这也是我提供的链接中所写的内容。但适用于所有其他 id 生成器。这不是 Hibernate 的错,而是数据库提供程序的问题以及它们向 jdbc 公开的内容。关于第二条评论,我完全同意,当使用 ORM 时,人们倾向于将它用于所有事情(用锤子,每个问题都像是钉子),尽管大多数 ORM 解决方案都为原生查询提供了丰富的 API。与往常一样,这只是为工作选择正确工具的问题。