【问题标题】:Should I use multi threading我应该使用多线程吗
【发布时间】:2016-07-02 14:49:38
【问题描述】:

我正在用 java 编写一个函数来生成并使用休眠模式保存一个唯一代码,然后在 get 请求中发送它,我将不得不在一次调用中执行此操作 30,000 次。

即使我无法将 HttpRequest 与休眠插入分开,多线程是否会帮助我加快速度?

【问题讨论】:

    标签: java multithreading hibernate httprequest


    【解决方案1】:

    您愿意尽可能快地进行 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 个东西?您是否逐字节插入图片?

    【讨论】:

    • 不错的评论。但是为什么你认为 Hibernate 在批处理方面效率低下?实际上,自动批处理一直是 ORM 解决方案中最受推崇的特性之一。可能需要some configurations,但我从来没有遇到过问题。
    • @DraganBozanovic,我发现 Hibernate 的工作方式不尽如人意。作为一名 10 多年的数据库架构师,我可能抱有太大的期望 :) 我在一年前左右测试过这个。当插入涉及身份生成器时,批处理根本不起作用。取而代之的是,Hibernate会生成很多select next id,然后insert操作,一个一个执行。批量更新也不无耻:vladmihalcea.com/2015/03/18/…
    • 当然,ORM 工具和 Hibernate 是很好的工具,它们的构建目的是 - 将对象映射到表行。但是一旦我们从这里出去,访问多行,需要受益于特定数据库的SQL操作,那就是一个诅咒。 ORM 的意义——即在 yoru 应用程序的有意义的域模型和数据库的优化存储模型之间的映射——可以用其他解决方案做得更好。我发现 PL/SQL 数据访问抽象层工作得更好,而且我可以完全控制查询执行和优化。 YMMV,当然 :)
    • 关于批处理,它不适用于identity 类型的 id 生成器,是的,这也是我提供的链接中所写的内容。但适用于所有其他 id 生成器。这不是 Hibernate 的错,而是数据库提供程序的问题以及它们向 jdbc 公开的内容。关于第二条评论,我完全同意,当使用 ORM 时,人们倾向于将它用于所有事情(用锤子,每个问题都像是钉子),尽管大多数 ORM 解决方案都为原生查询提供了丰富的 API。与往常一样,这只是为工作选择正确工具的问题。
    • 其实——我真的不是Hibernate的粉丝,你一定注意到了——单id生成不是db供应商的错。例如,在 Oracle 中(就像任何其他数据库一样,一个一个地给出序列)你可以做 select level,seq1.nextval from dual connect by level
    猜你喜欢
    • 1970-01-01
    • 2019-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-25
    • 1970-01-01
    • 2023-03-06
    相关资源
    最近更新 更多