关于集合的性能问题
关于集合的性能问题
猪刚烈 发表于3年前
关于集合的性能问题
  • 发表于 3年前
  • 阅读 4
  • 收藏 0
  • 点赞 0
  • 评论 0

1.Bag 是所有非反向集合类型中性能最差的(但却是反向集合中性能最好的,还有list。)。因为 bag 允许重复的元素值,也没有索引字段,因此不可能定义主键。
Hibernate 无法判断出重复的行。当这种集合被更改时,Hibernate 将会先完整地移除 (通过一
个(in a single DELETE))整个集合,然后再重新创建整个集合。因此 Bag 在非反向集合中是非常低效的。

这一点我已做过验证,确实如文档所说:如果bag集合有任何变动,hibernate会删除集合中的所有元素(通过一个delete),然后重新把最新状态的集合一条条插入数据库。之所以会出现这种情况是因为bag允许有重复的元素,并且是无序,bag元素对应的表既不会生成主键,也不会建立索引列。这样一来,一旦集合有任何更新,hibernate根本不知道是要更新数据库中的哪条记录,因此只能删除全部数据重建!换句话说:对于bag集合,一旦它从数据库中加载到内存中,hibernate根本没办法知道内存中的一个对象对应于数据库中的哪条记录!因此,如果有更新,只能是全部删除重新再建。

在把 bag 扔进水沟之前,你必须了解,在一种情况下,bag 的性能(包括list)要比 set 高得
多:对于指明了 inverse="true" 的集合类(比如说,标准的双向的一对多关联),我们可以在未
初始化(fetch)包元素的情况下直接向 bag 或 list 添加新元素! 这是因为 Collection.add())
或者 Collection.addAll() 方法对 bag 或者 List 总是返回 true(这点与与 Set 不同)。因此
对于下面的相同代码来说,速度会快得多。
Parent p = (Parent) sess.load(Parent.class, id);
Child c = new Child();
c.setParent(p);
p.getChildren().add(c); //no need to fetch the collection!
sess.flush();

简单总结一下原则:

如果是标准的父子关系,并且集合设置了inverse=true,那么可以使用bag。

如果是单向的one-to-many,切勿使用bag!而应该使用set!

以下是Hibernate文档对各种集合性能的总结:

list,map 和 idbags 是最高效的非反向(inverse=false)集合类型,set 则紧随其后。Bag最差.

 

Bag 和 list 是反向集合(inverse=true)中效率最高的

在 Hibernate 中,set 应该时最通用的集合类型,这是因为“set”的语义在关系模型中是最自然的。

对于inverse=true的one-to-many集合,可以不考虑集合的性能。因为对于集合的更新是在many方处理的。

对于没有设定inverse=true的one-to-many集合(绝大多数情况是这是一个单向集合),最好选择set.bag是一定不要用的。

对于单向one-to-many(inverse必定为false),绝不能用bag,推荐set.

对于双向one-to-many(一般inverse都会设为true),选哪一种集合并无太大差别。

踪上,set是最为普遍使用的一种集合。使用它不会出现太大的性能问题。

将会先完整

将会先完整

将会先完整将会先完整

 

共有 人打赏支持
粉丝 22
博文 708
码字总数 110
作品 1
×
猪刚烈
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: