我无法让Hibernate在MySQL上执行批量插入。
我正在使用Hibernate 3.3和MySQL 5.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个),如下所示:
Hibernate:插入ProjectEntity(name,parent_id, path,project_id,state,type)值 (?,?,?,?,?,?)
我希望看到这个被批处理,所以更新更高效。这个例程可能会导致生成数万行,并且每行数据包跳闸是一个杀手。
为什么不进行批量处理? (我的理解是批处理插入在hibernate适当的地方应该是默认的。)
答案 0 :(得分:7)
rewriteBatchedStatements=true
参数。
此参数使JDBC驱动程序动态地重写INSERT批处理以使用单个“多值”INSERT,例如:
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。
答案 1 :(得分:5)
如Chapter 13. Batch processing中所述:
如果您正在进行批量处理 处理你需要启用 使用JDBC批处理。这是 如果你愿意,绝对必要 实现最佳性能。设置 JDBC批量大小合理的数量 (例如10-50):
hibernate.jdbc.batch_size 20
Hibernate禁用插入批处理 如果您透明地使用JDBC级别 使用身份标识符生成器。
不要忘记定期flush
然后clear
会话,否则13.1. Batch inserts中会记录OutOfMemoryException
。
但IMO,对于数万行,您应该考虑使用the StatelessSession
interface。
答案 2 :(得分:0)
Pascal几乎已经在hibernate上下文中钉了它。作为替代方案,您可以使用jbdc模板的Batchsqlupdate。但是我必须警告你,hibernate缓存的实例可能无法反映使用上面所做的更改。在我们的项目中,我们必须采取预防措施来克服这个问题,制定一个不同的时间表(创建另一个问题,但在我们的控制范围内)