代码之家  ›  专栏  ›  技术社区  ›  Marty Pitt

Hibernate/MySQL大容量插入问题

  •  5
  • Marty Pitt  · 技术社区  · 16 年前

    我无法让Hibernate在MySQL上执行大容量插入。

    我使用的是Hibernate3.3和MySQL5.1

    从高层来看,这是正在发生的事情:

    @Transactional
    public Set<Long> doUpdate(Project project, IRepository externalSource) {
        List<IEntity> entities = externalSource.loadEntites();
        buildEntities(entities, project);
        persistEntities(project);
    }
    public void persistEntities(Project project) {
         projectDAO.update(project);
    }
    

    这将产生n个日志条目(每行1个),如下所示:

    休眠:插入到ProjectEntity(名称、父级\u id, 路径、项目ID、状态、类型)值 ??????)

    我想看到这个被成批处理,所以更新更具性能。这个例程可能会生成数万行,每行的db trip是一个杀手。

    为什么这个不成批?(我的理解是,在适当的情况下,Hibernate应该默认批量插入)。

    3 回复  |  直到 15 年前
        1
  •  5
  •   Pascal Thivent    16 年前

    Chapter 13. Batch processing :

    如果你要批量生产 处理您需要启用 使用JDBC批处理。这是 如果你想的话绝对必要 实现最佳性能。设置 JDBC批量大小到合理的数量 (例如,10-50):

    hibernate.jdbc.batch_size 20
    

    休眠禁用插入批处理 如果您 使用标识标识符生成器。

    别忘了 flush 然后 clear 定期开会,否则你会 OutOfMemoryException 如中所述 13.1. Batch inserts .

    但在我看来,对于成千上万的行,您应该考虑使用 the StatelessSession interface .

        2
  •  7
  •   Matt Solnit    16 年前

    帕斯卡的回答是正确的。但是,由于您使用的是MySQL,我强烈建议您尝试使用 rewriteBatchedStatements=true JDBC URL中的参数。

    此参数使JDBC驱动程序动态地重新编写插入批,以使用单个“多值”插入,例如:

    INSERT INTO mytable (mycol) VALUES (0);
    INSERT INTO mytable (mycol) VALUES (1);
    INSERT INTO mytable (mycol) VALUES (2);
    

    将被重新写入:

    INSERT INTO mytable (mycol) VALUES (0), VALUES (1), VALUES (2);
    

    在某些情况下,这可能会产生显著的差异。见 http://www.jroller.com/mmatthews/entry/speeding_up_batch_inserts_for 例如测量。

        3
  •  0
  •   questzen    16 年前

    帕斯卡在冬眠的环境中已经把它钉住了。另外,您可以使用jbdc模板的batchsqlupdate。但是,我必须警告您,Hibernate缓存实例可能不会反映使用上述方法所做的更改。在我们的项目中,我们必须采取预防措施来克服这一点,通过创建一个不同的时间表(创建了另一个问题,但在我们的控制范围内)