Hibernate性能调优_第1页
Hibernate性能调优_第2页
Hibernate性能调优_第3页
Hibernate性能调优_第4页
Hibernate性能调优_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、2.使用双向关联, inverse= “trueHibernate性能调优关键字:hibernate性能调优、inverse = ?inv erse=false(default)用于单向one-to-many关联pare nt.getChildre n( ).add(child) /in sert childpare nt.getChildre n( ).delete(child) / delete childinv erse=true用于双向one-to-many关联child.setPare nt(pare nt); sessi on. save(child) / i nsert chil

2、dsessi on. delete(child)在分层结构的体系中parentDao, childDao对于CRU的圭寸装导致往往直接通过 session接口持久化对象,而很少通过关联对象可达性、one-to-many 关系单向关系还是双向关系?pare nt.getChildre n( ).add(child)对集合的触及操作会导致lazy的集合初始化,在没有对集合配置二级缓存的情况下,应避免此类操作select * from child where pare nt_id = xxx;性能口诀:3.在分层结构中通过DAO接 口用session直接持久化对象,避免通过关联关系进行可达性持久化、

3、 many-to-one 关系单向 many-to-one 表达了外键存储方灵活运用 many-to-one 可以避免一些不必要的性能问题many-to-one表达的含义是:O.n : 1 , many可以是0,可以是1,也可以是n,也就是说 many-to-one可以表达一对多,一对一,多对一关系因此可以配置双向 many-to-one 关系,例如:1.many-to-one 的关系一桌四人打麻将,麻将席位和打麻将的人是什么关系?是双向四、one-to-one通过主键进行关联相当于把大表拆分为多个小表例如把大字段单独拆分出来,以提高数据库操作的性能Hibernate的 one-to-one

4、似乎无法 lazy ,必须通过 bytecode enhancement五、集合 List/Bag/Setone-to-many1. List 需要维护 index column ,不能被用于双向关联,必须 inverse= “false ”,被谨慎的使用在某些稀有的场合2. Bag/Set 语义上没有区别3. 我个人比较喜欢使用 Bag many-to-many1. Bag 和 Set 语义有区别2 。 建议使用 Set六、集合的过滤).setFirst1. children = session.createFilter(parent.getChildren(), where this.ag

5、e > 5 andthis.age < 10 ”).list()页:针对一对多关联当中的集合元素非常庞大的情况,特别适合于庞大集合的分session.createFilter(parent.getChildren(),Result(0).setMaxResults(10).list();七、继承关系当中的隐式多态HQL: from Object1. 把所有数据库表全部查询出来2. polymorphism= “ implicit ” (default) 将当前对象,和对象所有继承子类全部一次性取出八、Hibernate 二级缓存著名的n+1问题:from Child,然后在页面上面

6、显示每个子类的父类信 息,就会导致 n 条对 parent 表的查询:select * from parent where id = ?select * from parent where id = ?解决方案1. eager fetch2. 二级缓存九、in verse和二级缓存的关系当使用集合缓存的情况下:1. inverse= “false ”,通过 parent.getChildren() 来操作, Hibernate 维护集合缓存2. inverse= “true ”,直接对 child 进行操作,未能维护集合 缓存!导致缓存脏数据3. 双向关联, inverse =“true ”的

7、情况下应避免使用集合缓存十、Hibernate二级缓存是提升web应用性能的法宝OLTP 类型的web应用,由于应用服务器端可以进行群集水平扩展, 最终的系统瓶颈总是逃不开数据库访问;哪个框架能够最大限度减少数据库访问,降低数据库访问压力, 哪个框架 提供的性能就更高;针对数据库的缓存策略:1. 对象缓存:细颗粒度,针对表的记录级别,透明化访 问,在不改变程序代码的情况下可以极大提升 web应用的性能。对象缓存是ORM勺制胜 法宝。2. 对象缓存的优劣取决于框架实现的水平, Hibernate是目前已知对象缓存最强大的开源 ORM3.实时化要求不高的场合查询缓存:粗颗粒度,针对查询结果集,应用

8、于数据一、应用场合决定了系统架构、是否需要 ORMHibernate or iBATIS ?、采用ORh决定了数据库设计Hibernate:倾向于细颗粒度的设计,面向对象,将大表拆分为多个关联关系 的小表,消除冗余column,通过二级缓存提升性能(DBA比较忌讳关联关系的出现,但 是ORM勺缓存将突破关联关系的性能瓶颈);Hibernate的性能瓶颈不在于关联关系, 而在于大表的操作iBATIS :倾向于粗颗粒度设计, 面向关系, 尽量把表合并, 通过表 column 冗余,消除关联关系。无有效缓存手段。 iBATIS 的性能瓶颈不在于大表操作,而在于关 联关系。总结:性能口诀1 、使用双向

9、一对多关联,不使用单向一对多2 、灵活使用单向多对一关联3 、不用一对一,用多对一取代4 、配置对象缓存,不使用集合缓存5 、一对多集合使用Bag,多对多集合使用Set6 、继承类使用显式多态7 、表字段要少,表关联不要怕多,有二级缓存撑腰hibernate与应用缓存方案总结关键字:hibernate与应用缓存方案总结XXXX项目是目前在实际工作中正在做的事情,该项目是一个大型系统的内容管理内核, 负责最核心的meta data的集中管理,性能有较高的要求,设计初期就要求能够支持 cluster。项目使用hibernate 3.2,针对开发过程中对于各种缓存的不同看法,撰写了 本文。重点在于澄

10、清一些hibernate的缓存细节,纠正一些错误的缓存用法。、hibernate的二级缓存如果开启了二级缓存,hibernate在执行任何一次查询的之后,都会把得到的结果集放 到缓存中,缓存结构可以看作是一个 hash table ,key是数据库记录的id,value是id 对应的pojo对象。当用户根据id查询对象的时候(load、iterator 方法),会首先 在 缓存中查找,如果没有找到再发起数据库查询。但是如果使用hql发起查询(find, query 方法)则不会利用二级缓存,而是直接从数据库获得数据,但是它会把得到的数据放到 二级缓存备用。也就是说,基于 hql的查询,对二级缓

11、存是只写不读的。针对二级缓存的工作原理,采用iterator 取代list来提高二级缓存命中率的想法是不可行的。Iterator的工作方式是根据检索条件从数据库中选取所有目标数据的id,然后用这些id 一个一个的 到二级缓存里面做检索,如果找到就直接加载,找不到就向数 据库做查询。因此假如iterator 检索100条数据的话,最好情况是100%全部命中,最 坏 情况是0%命中,执行101条sql把所有数据选出来。而list虽然不利用缓存,但是 它只会发起 1条 sql 取得所有数据。在合理利用分页查询的情况下, list 整体效率高 于 iterator 。二级缓存的失效机制由 hibern

12、ate 控制,当某条数据被修改之后, hibernate 会根据它 的 id 去做缓存失效操作。基于此机制,如果数据表不是被 hibernate 独占(比如同时 使用 jdbc 或者 ado 等),那么二级缓存无法得到有效控制。由于 hibernate 的缓存接口很灵活, cache provider 可以方便的切换,因此支持 cluster 环境不是大问题,通过使用 swarmcache、 jboss cache 等支持分布式的缓存方案,可以 实现。但是问题在于 :1、 分布式缓存本身成本偏高(比如使用同步复制模式的 jboss cache )2、分布式环境通常对事务控制有较高要求,而目前的

13、开源缓存方案对事务缓存 ( transaction cache )支持得不够好。当 jta 事务发生会滚,缓存的最后更新结果很 难预料。这一点会带来很大的部署成本,甚至得不偿失。结论:XXXX不应把hibernate二级缓存作为优化的主要手段,一般情况下建议不要使用原因如下:1、XXXX的DAO类大部分是从1.0升级过来,由于1.0采用的是hibernate 2.1,所以 在批量删除数据的时候采用了native sql的方式。虽然XXXX2.0已经完全升级到hibernate 3.2 ,支持 hibernate 原生的批量删改,但是由于 hibernate 批量操作的性 能不如sql,而且为了

14、兼容1.0的dao类,所以很多地方保留 了 sql操作。哪些数据表 是单纯被 hibernate 独占无法统计,而且随着将来业务的发展可能会有很大变数。因此 不宜采用二级缓存。2、 针对系统业务来说,基于 id 检索的二级缓存命中率极为有限, hql 被大量采用, 级缓存对性能的提升很有限。3、hibernate 3.0 在做批量修改、批量更新的时候,是不会同步更新二级缓存的,该 问题在 hibernate 3.2 中是否仍然存在尚不确定。、 hibernate 的查询缓存查询缓存的实现机制与二级缓存基本一致, 最大的差异在于放入缓存中的 key 是查询的 语句,value是查询之后得到的结果

15、集的id列表。表面看来这样的方案似乎能解决hql 利用缓存的问题,但是需要注意的是,构成key的是:hql生成的sql、sql的参数、排序、分页信息等。也就是说如果你的 hql 有小小的差异,比如第一条 hql 取1-50 条数 据,第二条hql取20-60条数据,那么hibernate会认为这是两个完全不同的key,无 法 重复利用缓存。因此利用率也不高。另外一个需要注意的问题是,查询缓存和二级缓存是有关联关系的,他们不是完全独立 的两套东西。假如一个查询条件 hql_1 ,第一次被执行的时候, 它 会从数据库取得数据, 然后把查询条件作为 key ,把返回数据的所有 id 列表作为 val

16、ue (请注意仅仅是 id ) 放到查询缓存中,同时整个结果集放到class缓存(也就是二级缓存),key是id , value 是pojo对象。当你再次执行hql_1,它会从缓存中得到id列表,然后根据这些列表一 个一个的到 class 缓存里面去找 pojo 对 象,如果找不到就向数据库发起查询。也就是 说,如果二级缓存配置了超时时间(或者发呆时间),就有可能出现查询缓存命中了, 获得了 id 列表,但是 class 里面相应的 pojo 已经因为超时 ( 或发呆)被失效, hibernate 就会根据id清单,一个一个的去向数据库查询,有多少个id,就执行多少个sql。该情况将导致性能下

17、降严重。查询缓存的失效机制也由 hibernate 控制,数据进入缓存时会有一个 timestamp ,它和 数据表的 timestamp 对应。当 hibernate 环境内发生 save、 update 等操作时,会更新 被操作数据表的 timestamp 。用户在获取缓存的时候, 一旦命中就会检查它的 timestamp 是否和数据表的 timestamp 匹配, 如果不, 缓存会被失效。 因此查询缓存的失效控制是 以数据表为粒度的, 只要数据表中任何一条记录发生一点修改, 整个表相关的所有查 询 缓存就都无效了。因此查询缓存的命中率可能会很低。结论:XXXX不应把hibernate二级缓存作为优化的主要手段,一般情况下建议不要使用。原因如下:1、XXXX的上层业务中检索条件都比较复杂,尤其是涉及多表操作的地方。很少出现重 复执行一个排序、分页、参数一致的查询,因此命中率很难提高。2、查询缓存必须配合二级缓存一起使用,否则极易出现 1+N的情况,否则性能不升反 降3、使用查询缓存必须在执行查询之前显示调用Query.setCacheable(true)才能激活缓存,这势必会对已有的hibernate圭寸装类带来问题。总结详细分析hibernate的二级缓存和查询缓存之后,针对XX

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论