hibernate的批量删除,大家怎么做的?
是利用主子表的方式,删除所有子表。
把 hibernate.jdbc.batch_size 50 尽量设的大些,可以得到接近JDBC的删除速度。
我觉得不可能,hibernate要先select出来,再delete。
还是写jdbc来做batch delete,update吧
我的测试:
Oracle817,ojdbc14.jar 表记录1万条,全部删除。
JDBC:
sql语句 delete from cat
速度:平均6s
Hibernate:
session.delete("from Cat as c");
==> select id,name,sex,weight from cat;
==> delete from cat where id = ?
Batch Size = 0 速度: 25s
Batch Size = 50 速度: 6s
而正确的jdbc批量删除只要执行一个删除sql语句,
对于数据库来说
执行一个删除sql语句 的时间 要远小于一个batch operation
原因很简单,对于决大多数jdbc ,batch operation只是将多条
数据库操作一次发到db server,避免多次网络连接,而到了数据库
之后还是一条一条执行,每一条执行都是一次表扫描,性能远小于执行一个删除sql语句。
你的测试时间接近,是你的表简单了,换一个复杂的表试一试吧
可以肯定,用jdbc批量删除要比hibernate好很多,其实没法比
前提:用一个sql或有限的几个sql来完成批量删除。
b t w
需要这么酷吗?
很早之前的一个帖子里面我就说过批量删除和批量更新建议用JDBC,这是一个原则,当然有的时候可能必须用Hibernate来批量更新和批量删除,那么这个时候我想说的就是,Hibernate批量更新和删除效率并非传说中的那么差,只要优化的好,速度也非常快。
Hibernate先查询数据,确实要消耗一些时间,但是select只读操作和insert,delete,update这些数据库修改操作在速度上有一个以上的数量级的差距。所以Hibernate虽然查询数据要多耗时,但是消耗的这点时间影响不是很大,主要是内存消耗的多。
JDBC: delete from table_name; 这个sql不清楚数据库是怎么进行解析和执行的,从我多次的测试来看,Oracle似乎内部也是把主键找出来,然后按照主键依次删除(即使没有主键,也有rownum之类的东西),这样来看,其实和Hibernate的删除方式没有本质差别,Hibernate主要差距在PO的同步和多次的网络通讯数据传输上。其实当删除大量数据的时候,主要的瓶颈在数据库的硬盘IO上,所以以上的那些差距影响因素就显得不那么重要了,这也是为什么Hibernate批量删除速度有可能接近JDBC的原因。
BTW:Oracle的delete语句其实是很慢的,truncate才是快速删除
case 1
delete from tab where id = 1
delete from tab where id = 2
delete from tab where id = 3
delete from tab where id = 4
delete from tab where id = 5
...
delete from tab where id = 10000
case 2
delete from tab where id+0 =< 10,000
case 2 的执行效率要高很多尤其是表数据大于100,000时
如果hibernate的删除是case 1的话,那还是用索引比较好(每一条
的定位不需要做全表扫描)。
对于case 2,快的原因是一次全表扫描删除了所有10000行
呵呵,我也是hibernate的忠实拥护者。
BTW:tracunt(忘了怎么拼的了)是表截断,根本不做全表扫描,当然快
可表里一条数据也剩不下了。