论坛首页 Java企业应用论坛

为何每次问到传统sql如何调优就没人回答?另附几则hibernate性能优化实践

浏览 59354 次
该帖已经被评为良好帖
作者 正文
   发表时间:2010-03-24  
抛出异常的爱 写道
nighthawk 写道
讨论得这么热闹,忍不住了还是要说两句。
老抛跟我观点一致 ,这里讨论的有些东西容易走极端,喜欢举大规模大并发的大系统来作为讨论的基础。
但是很遗憾,我相信大部分草根程序员可能没有机会接触到。
高 ,大并发系统中出现的问题来指责甚至怀疑hibernate,哪怕其他任何一个流行框架,都是不公平的。


那么最终还是回到这个问题上,你们用hibernate的动机是什么?

我先说说我的,之前有几个项目都用过hibernate,我当初喜欢他的理由还是之前说过的,ORM,面向对象。以领域模型的方式去解决问题,多美啊。这简直就是终极目标了。于是我忍受了mid-gen给我生成的xml还有一堆的贫血模型。我也忍受了那怪异的HQL,甚至某些解决方案里提到的opensessioninview模型我也忍了。
我都付出这么多代价了,那后来呢,我发现我和我的搭档们无非就是把SQL换成了HQL
我开始怀疑并检讨我的水平了,一定是我用的不对,我买来了很多宝典,evans的领域驱动开发,pojos in action,泡javaeye看robbin以及众多大牛们关于领域模型的讨论。但不幸的是,依然没有结论,而且大牛们开始搞ruby了。

不过幸运的是,性能问题不是困扰我的原因。几个项目也能上线,虽然过程丑陋了点。

这个过程,我依然不敢质疑hibernate。我怕有人说我拉不出屎来怪茅坑。

那最后就只能怪我没有领悟领域驱动的精髓了。在我没有领悟之前,现在还是踏实的继续jdbctemplate吧。

虽然目标仍在,但依然飘渺。

我认为主要是书。。。。培训跟不上。
看了24小时学会系列的ssh同学们太多。
大牛们对新手这样那样的问题视而不见。。。。。
说什么早就说过不能这样用了。。。。。
哪本书能把这些东西收全了?
Oracle我有三本板砖
hibernate我的书更多但写的都差不多。

7天学会ss,问题是不大的。大概用起来,大同小异,用的粗浅些,也不会有什么毛病

h比前2个深的多复杂的多,前2个可以看demo照搬,最后一站h不行
1 请登录后投票
   发表时间:2010-03-24  
本人觉得hibernate不能单纯拿来与jdbc这种所谓的用原生sql进行数据库操作的方式来完全比较,这样的比较只是一部分,hibernate有其优点与缺点,这是无可争议呢?但这些所谓的优点与缺点也是相对的,我们不再展开话题去讨论其好与坏!那么楼主讨论的是与原生SQL相比,hibernate性能问题,特别是很多人提到的N+1,但是我们反过来想想,一般的应用中,hibernate的session基本等同于一次请求那么如果要查询是不是也对应一次connection呢?所以这个N+1性能真的就那么差吗?请注意,N的条件字段,如果没用错的话应该是主键吧.如果用二级缓存的话,这个主键就是map的key,如果不做的话,就是去查询数据库,也是通过主键查询的,请问这只是在一次连接中,查询的性能会影响很大吗?而如果不用N+1,大多数用的是left join吧?谁又能说这个的查询的性能一定会比N+1的N是按主键查询快呢?
所以查询性能本人认为:
1,如果项目非常依赖数据库的话,可以由DBA+程序员一起来解决
2,如果不是很依赖数据库的话,那么缓存是一个值得推荐的东西!
0 请登录后投票
   发表时间:2010-03-24  
miaow 写道
我们一般是团队没有专职DBA,有指定的DBA支援。
数据库设计团队做,DBA要看。
SQL代码设计团队写,DBA不主动去看,团队要识别性能问题点主动找DBA。
测试中的性能问题是一定要一起坐下来看的。
如果数据量大一些,性能方面的考虑要尽早,基本冒烟过了压力测试就会冲上来。


从你的描述看你们的分工大致这样:

数据库设计  数据库设计团队
SQL代码设计 SQL代码设计团队
DBA
程序员
测试团队

怎么解决沟通问题呀。

1.现实中库表可能经常变动
2.代码和sql之间是紧密耦合的怎么分功呀?
3.sql、代码、数据库、同时都反映着需求,需求如何在这么些团队间保持一致呀?

看来这管理工作 相当难做了。
0 请登录后投票
   发表时间:2010-03-24  
gdpglc 写道
从你的描述看你们的分工大致这样:

数据库设计  数据库设计团队
SQL代码设计 SQL代码设计团队
DBA
程序员
测试团队

怎么解决沟通问题呀。

1.现实中库表可能经常变动
2.代码和sql之间是紧密耦合的怎么分功呀?
3.sql、代码、数据库、同时都反映着需求,需求如何在这么些团队间保持一致呀?

看来这管理工作 相当难做了。

没那么复杂,不存在
gdpglc 写道
数据库设计  数据库设计团队
SQL代码设计 SQL代码设计团队

这些并没有单独的团队,只有一个开发团队。这样需求的问题也不存在。

表结构要DBA看,一般的业务字段加减DBA不看的——DBA才没这么“热情”。

代码和sql有耦合这事一般也不用解决。
我很怀疑,只要有用hib/toplink/eb不能完全搞定而手写的sql,真有分离的代码么。
0 请登录后投票
   发表时间:2010-03-24  
godson_2003 写道
对于大表的N+1问题 我们在设计数据库的时候为什么不适当的冗余呢?

产品表完全可以冗余产品分类

解决办法后很多



赞同你的观点!
0 请登录后投票
   发表时间:2010-03-24  
xyz20003 写道
大多数反对使用hibernate的同志,张口必说hibernate有性能问题,不好调优,对DBA不友好。可从来没有任何一个人具体指出hibernate哪里有性能问题,为什么不能调优,哪方面对DBA不友好。

大家去面试过,有些同志也有面试别人的经验,应该明白一点:务虚很容易。什么性能啦,什么并发啦,什么管理啦。每个人张口都可以说出很多来,但是一旦开始玩真格的,那些没有实际经验的就会原型毕露了。不是我心眼坏,戴着有色眼镜去看人,而是社会复杂,害人之心不可有,防人之心不可无。精准的批评是一种鞭策,有则改之无则加勉。关键在于是否存在“三人成虎”的情况呢?

让咱们化繁为简吧,只问一句话:“阁下认为hibernate有性能问题,sql无法调优。”这个想法是切身体会呢?还是以讹传讹而来呢?如果是切身体会,那么恳请阁下受累一下,劳烦您把出现的问题稍微详细的描述一下,如果有可能的话,最好还能和大家稍微讨论一下这个问题出现的原因,以及解决方法。

下面算是我在实际项目中遇到的一些性能出现问题的场景,以及解决的方法,想必大家用过hibernate都应该耳闻能熟了,但是为了避免自己出现上面所说的“空口无凭”,还是斗胆拿出来献丑了。

1.N+1
  场景描述:产品product和产品分类product_category两张表,多对一关系。查询产品列表时,可能出现N+1问题。
  解决方法:
   1:使用fetch抓取,select p from Product p join fetch p.category c
   2:使用map直接搜索需要的列,select new Map(p.id as id, p.name as name, p.category.name as categoryName) from Product p

2.1:1无法lazy
  场景描述:申请表头和三张申请子表是一对一关系,其中子表对主表的关联可以实现延迟加载,主表无法延迟加载3个子表。造成每次读取主表以后,都同时发送三个sql查询三个子表的信息。
  解决方法:一对一关系的一方无法延迟加载是hibernate本身的bug,虽然可以使用instrument解决,但是要对字节码进行静态加强,不如直接改成多对一关联。

3.大批量插入数据
  场景描述:导入数据过多时,一级缓存会迅速膨胀,有时导致内存溢出。
  解决方法:我们用的方法是每隔一定数目(200条)就执行session.flush()和session.clear(),现在看来还是应该是用jdbc批量插入,或者应该直接导入到数据库里。

回过头来看一下,平常遇到的问题,基本都是因为N+1以及延迟加载使用的太随意造成的,我们对二级缓存的使用也不多,只是把一些常用的数据字典一次性缓存到内存里了。剩下的批量插入,批量更新,确实不应该依靠hibernate来解决,这时候幸好我们还有其他选择,使用hibernate也可以满足我们80%以上的需求。

下面就期待同仁提出实例反证了,向大家多多学习。



本人不才  看了楼主的帖子和下面各位大牛的激烈讨论,忍不住说两句

核心命题: 性能问题

1hibernate为什么而存在?
  项目有大小之分,构建时期之分,用途和关注点之分 直接比较系统的性能肯定是一无所获  所以楼主说的性能应该是指的是一个面向关系数据库的java系统在不同数据库产品上原生jdbc和使用hibernate取得数据时的性能差异
   这样就出问题了,因为据本人的理解,hibernate的存在不是为了提升所谓的sql查询性能,而是为了作为流行的orm框架提高面向对象开发效率的,一面是面向对象的java程序,一面是不和谐的关系数据库结构,orm类产品的出现是必然的.

2使用jdbc和hibernate的系统哪个性能好?
  首先hibernate不是写了什么native方法,和厂商合作推出的独立产品,他是基于jdbc api的封装,所以一般来说大多数情况使用hibernate都会比jdbc慢,但事情也不是绝对的,在hibernate提供orm的同时也提供了缓存,面向对象的索引等等,在某些场景下,sql写的不恰当反而比hibernate对象包装查询时还慢
  这又出问题了,因为系统的性能不是sql的执行性能,系统的性能好不好避开设计不谈,并不是单条查询语句决定的,而是系统在适用条件下长期运行的综合评判,而综合评判里面的因素就多了, 算本人废话了,只能具体问题具体分析了.

3jdbc和hibernate如何取舍?
   取舍需要看需求,如果是性能问题,请参照点2, 如果是项目经理来选,是否适合他的项目,重点考量的就是是否走orm套路,走这个套路是自己实现还是用hibernate,亦或者是iBATIS等其他产品 ,这些产品第三方支持,风险,程序员掌握程度等等

以上是本人的拙见,各位讨论的都集中到2上面, 本人能力有限,实际工作中如何选择真不是那么简单的,但是请参考条1,hibernate存在的目的,意义和定位 希望不要被误解和滥用

以下是对于各位评论提到问题的看法

高性能,高并发,大数据量,hibernate无法胜任:
遇到这种需求,本人认为无法胜任不是hibernate性能的问题,
1 如果是hibernate性能问题,为什么不选用其他orm的框架?
因为hibernate本质是个中间组件,这样的情况也一般不会选用其他orm产品,hibernate定位为轻量级普遍性框架,因为是项目本身不适合用hibernate类框架.
2 用纯jdbc和sql能满足需求?
    如果答案是肯定的,, 本人个人认为多半不是因为hibernate性能问题,而是hibernate的局限,比如一些大公司是不会选择开源框架的,内部会有一套类似的框架,也有自己实现事务,缓存,bean管理,对象索引,当然不用hibernate
3 用纯jdbc和sql也不能满足需求
   大家大多数说的是这种情况,当然hibernate也无法满足了  典型的是新浪,Facebook等,对于传统关系数据库的局限,基本上都是用缓存缓解压力, 也有的换掉了关系数据库,本人只是听说个大概,详情并不了解



 
0 请登录后投票
   发表时间:2010-03-24   最后修改:2010-03-24
jmu 写道

  首先hibernate不是写了什么native方法,和厂商合作推出的独立产品,他是基于jdbc api的封装,所以一般来说大多数情况使用hibernate都会比jdbc慢

不知你说慢的原因是什么? 慢多少,能不能量化一下?
0 请登录后投票
   发表时间:2010-03-24  
gdpglc 写道
jmu 写道

  首先hibernate不是写了什么native方法,和厂商合作推出的独立产品,他是基于jdbc api的封装,所以一般来说大多数情况使用hibernate都会比jdbc慢

不知你说慢的原因是什么? 慢多少,能不能量化一下?

可能我没说清楚 这个慢是指向数据库发起查询到返回结果集的单个过程,  详细原因你肯定比我了解的多啊    hibernate已经做了很多优化,但都是针对hibernate容器的,  慢多少我不知道, 
0 请登录后投票
   发表时间:2010-03-24  
mdream 写道
Hibernate 因为是 ORM .在很多时候还是不能完全实现原生SQL的效率.

如果项目时间紧,这个时候就要最求的是快速开发.那么选择Hibernate.当然执行效率上就有点欠缺了.

我们项目:两台服务器,日PV过千万.采用的是原生SQL,和缓存技术.如果使用Hibernate,我估计是难以承受的.


你没修改过,只是估计,这个算证据吗?能说服谁?只能说你们公司用sql很成功,不见得Hiberante不能胜任啊。

这种逻辑真要命啊,明显是个人喜好情绪的表现啊
0 请登录后投票
   发表时间:2010-03-24  
guanliScott 写道
linliangyi2007 写道
lizhilin 写道


赞同你的观点

我说一个场景吧 每天千万次以上的访问 数据量在千万行以上 采用分库/分表

很多时候sql不是随便写的

楼上的场景是不是自己臆想的啊,太假了。

我自己,包括我认识的朋友,在碰到上千万词访问,且大数据量的时候,用到的多是缓存技术,多个级别的缓存,web文件应用层,当然也包括了数据库层(这里就包括hibernate的缓存技术)。

我的朋友在千橡(校内,现在叫人人)做sns,我在sohu。把具体的公司发出来不是显摆啥,就是要摆事实,不要老用臆想的概念误导大家。

你也可以问问天涯这样的大网站,他们是用缓存技术,还是让用户每次访问去查SQL哈~~~拜托,数据库就是存储为主的!


千橡,sohu这种网站架构都是前端有squid server, 后端集群app server, 个人觉得并不是高并发场景。
大型网络游戏,比如Wow(随便举例), real time统计每个人的积分排名,每个公会的排名,简直太费劲了。有些可以定时刷新的统计不算。


你用wow来例举,能证明什么?证明Hibernate不是为大型网游设计的?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics