hibernate分区mysql查询,业务系统中Hibernate连MySQL查询调优的一点总结

业务系统中使用Hibernate链接数据库的很多,在熟悉Hibernate的基础上做开发,可以大大缩短项目周期,提高开发效率,不用为类型转换、有效性判断、对象映射等等写重复代码。但是Hibernate本身的对象结构,以及设计思路,跟传统的直接SQL访问数据库还是有一些不同的。下面总结几个Hibernate的开发,在性能方面应该注意的几个点。

1、many-to-one级联对象的fetch是用select还是用join?

假如对象关系是A->B,如果用select的话,通过A对象获取B对象,Hibernate一定会再生成一条SQL语句:select

* from B b where

b.id=?。用惯SQL的同学一定极为不爽,既然A->B是必然使用的,为什么不在获取A的时候,一条SQL语句把B选出来呢,于是会把fetch善意的改成join。接着灾难开始了。系统里,除了A->B的关系,可能还存在C->A->B、D->A->B、E->C->A->B,如果手贱的把E->C->A->B的fetch属性都改成join,那你在获取E的时候,同时会join到C、A、B。E对象只通过主键获取一个对象倒还罢了,如果是一个几百万的列表呢?

在映射文件中使用join,是一种偷懒行为。如果真的需要直接join出B对象,可以在hql里使用“join

fetch”解决。首先,通过主键索引select出来的对象,往往比其他索引快一个数量级;其次,用hibernate一定要用其缓存机制,这里说的是其二级缓存机制。系统中如果再使用分页机制的话,几百万条A数据,要得到B数据,也就做几十个(取决于你每页数据量)主键索引的select,而且再次使用相应B对象的时候,会直接从缓存中拿。

2、一张大表装所有数据,还是多个小表级联呢?

单表单查询当然能获得最好的查询性能,所以很多做互联网的喜欢搞大表,逆范式,然后在表上堆索引,优化查询的时候使用强制索引。于是乎,用Hibernate的时候,也这么干。但是,Hibernate查询是基于对象的哦,每次select的时候,不管这个属性要不要都拿出来的,数据传输、转换都是要消耗系统资源的。另外,Hibernate不提供强制索引的能力,除非你自己写方言。搞大表是种惯性思维,Hibernate是在范式的思维下设计的。解决查询性能问题,需要综合考虑。如果已经做了大表,可以使用discriminator做一下对象继承关系,可以有效避免部分冗余数据的查询。

3、一条HQL,还是多条HQL

做数据库查询,往往喜欢用一条语句得到数据列表,多表级联就用join

fetch。SQL经验会告诉我们,1条搞定全部查询,是效率最高的,所以很多人比拼如何把语句凑成一条。首先一条语句解决一个查询的执行效率最高是否合理,可以参看我的另外一篇blog 《一条Mysql中的子查询in

(select)语句引发的血案》 ;另外,对于Hibernate来说,在有级联对象的时候,一条语句中的join

fetch,是用不到缓存的,而对于one-to-many的集合对象,查询效率更低。

一条select会承载太多的东西:where、distinct、order

by、group

by、limit,如果再加上join语句,性能肯定高不了。应该尽量避免无用的distinct;默认列表的查询条件应该都在主表;能不用order

by就不用;一对多关系的对象、group

by的数据可以考虑采用另外的hql语句;MySQL的limit没办法,几十万条以后,尾部的数据就是会慢。

总结下。数据对象尽量设计好,至少达到第二范式。Hibernate的查询,应该尽最大可能的利用好缓存,包括对象缓存、集合缓存和查询缓存。试试把你分页时的select

count(*) from A

where的查询放到缓存里,就可以提高一倍的查询效率了。没有二级缓存的Hibernate应用,是达不到应用级别的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值