论坛首页 Java版 Hibernate

鉴于反复出现讨论hibernate适用性问题的帖子,这次希望有个定论

浏览 35936 次
该帖已经被评为良好帖
作者 正文
最后更新时间:2007-12-27
robbin 写道
firmgoal 写道
我希望达到的目标,数据库查询返回应该是毫秒级的(<1s)。在实践中发现大表关联基本上没有毫秒级的,因此,我还是强调我的观点,可以通过冗余来避免关联,减少IO。


我手里没有Oracle数据库,所以没有办法做相应的测试,但是我觉得你的查询结果不可思议,查询毫无道理的慢,除非你的student表和resume表的字段太多,或者包含了大字段。像我在MySQL上面做的查询,但凡有效利用索引的关联查询,都不会超过1秒钟。

我建议你再测试一下单表查询,单独select student表和select resume表,加上同样的where条件和分页语句,看看执行时间。如果你的student和resume表关联查询这么慢的话,单独select resume表也不可能快的起来。

另外你的student表多少个字段?有没有blog/clob/long型的大字段,现在有多少条记录,表存储空间多大? resume表有多少个字段?有没有blob/clob/long型大字段,现在有多少条记录,表存储空间多大?这个信息很重要!

实际上关联查询并不一定慢,只要关联外键有索引,where条件有效索引可以约束扫描的表记录,关联查询并不见得会比单表查询慢,关键还是看查询语句实际造成了多少磁盘IO。所以查询性能低下的根源不在于关联查询,而在于表扫描造成的IO。


我又重新多执行了几遍查询,有可能是下午人多的时候,数据库有点慢(我是在生产机上做的)。Student+Resume关联查询大概是4-5秒,单查Resume表0.4-0.5秒。这两个表都没有B/C/L字段。Student表字段多一些,100来个,如果单取Student表的几个字段做关联查询的话,速度要快,大概1-2秒。

另外,关联外键目前有索引,RESUME_STU_GUID_IDX。慢得那么离谱可能是执行的时候,赶的时候太不巧了。应该我现在测试的时间准确。执行计划中没出现RESUME_STU_GUID_IDX,应该是这个索引操作包含在NESTED LOOPS里了,如果没有关联外键的话,应该是用SORTED MERGE或者HASH JOIN连接方式。
   
0 请登录后投票
最后更新时间:2007-12-28
你的表记录总量有多少? 不会是天文数字级的吧...
按道理超过1S就不太正常了,
我只对千万级的表测试过多种关联查询,完全可以做到毫秒内完成,前提是查询规则能合理用上索引。

试一下看这个?
select s.guid, ROWNUM as rowno 
   from student_base_info s 
      join resume r on s.guid=r.stu_guid 
where r.resumetime > to_date('2007-12-01','yyyy-mm-dd') AND rowno between 10000 and 10010
   
0 请登录后投票
最后更新时间:2007-12-28
blowfisher 写道
你的表记录总量有多少? 不会是天文数字级的吧...
按道理超过1S就不太正常了,
我只对千万级的表测试过多种关联查询,完全可以做到毫秒内完成,前提是查询规则能合理用上索引。

试一下看这个?
select s.guid, ROWNUM as rowno 
   from student_base_info s 
      join resume r on s.guid=r.stu_guid 
where r.resumetime > to_date('2007-12-01','yyyy-mm-dd') AND rowno between 10000 and 10010


rownum不能直接进行<比较吧?需要用内嵌表。
   
0 请登录后投票
最后更新时间:2007-12-28
robbin 写道

我仔细看了一遍你贴出来的执行计划,终于发现你关联查询慢的根源了!请看:


s.guid=r.stu_guid

你的关联查询关联外键上面根本就没有建立索引!这种关联查询会造成你的student表和resume表全表扫描,难怪会这么慢!

给student表的guid字段建立索引,然后给resume表的stu_guid字段也建立索引,再查询一遍,我保管你1秒钟查询完毕



期待firmgoal 的实际测试结果~~~~
   
0 请登录后投票
最后更新时间:2007-12-28
bulargy 写道
robbin 写道

我仔细看了一遍你贴出来的执行计划,终于发现你关联查询慢的根源了!请看:


s.guid=r.stu_guid

你的关联查询关联外键上面根本就没有建立索引!这种关联查询会造成你的student表和resume表全表扫描,难怪会这么慢!

给student表的guid字段建立索引,然后给resume表的stu_guid字段也建立索引,再查询一遍,我保管你1秒钟查询完毕



期待firmgoal 的实际测试结果~~~~



我上面已经答复了啊,测试的时候就是已经有外键索引了。
   
0 请登录后投票
最后更新时间:2008-01-09
timerri 写道
我有几个预言......

1.orm工具将被oodb取代.....
2.数据库索引和数据将被分开处理
3.分布式数据将成为应用主流...

jdbc,iBATIS,hibernate真的有本质区别么?扳手和活动扳手的区别罢了.....当然,你也可以选择用钳子...



赞一个,第一条我认同
   
0 请登录后投票
最后更新时间:2008-01-10
HIBERNATE有一些用法是不支持的

例如

1 左连接或右连接的时候,你只能连接它的子集(如果当初没有建立连接的话...)

2 部分COUNT无法计算,例如我查询某一个条件的条数,并且去处重复了,这个时候再统计数据就比较麻烦了

3 某些关联的查询在SQL里没有问题,但是同样或者类似的写法在HQL里就无法使用


所以我觉得如果不是有牛人作为技术支持的话,HIBERNATE最后不要用在大项目里,遇到越复杂的逻辑HIBERNATE用起来就越难以使用
   
0 请登录后投票
最后更新时间:2008-01-12
对于firmgoal的问题,我觉得可以直接在resume表上建标志字段,比如对行业参数加个industry char(30),(假设有30个行业选择),或用整型数的bit位表示,这样就没有关联表了.查询就用全索引扫描.
   
0 请登录后投票
最后更新时间:2008-01-12
另外,原先之所以有多个关联表,而不是像robbin那样设计只有一个,可能出于以下原因:如果一个resume选择4个地区,3个行业,3个职位,那么一个关联表的就有4*3*3=36条记录,而多个关联表则只有4+3+3=10条记录
   
0 请登录后投票
最后更新时间:2008-01-14
Qieqie 写道
1、hibernate没有什么是“意料之外”的故事,一切都显得理所当然,若有意外,那应该归功于盲从,而非被盲从的对象

2、使用hibernate,我不用去“SQL 跟踪、优化”,看几眼,感觉一下就够了。优化也轮不到SQL,更多的是你的数据库策略上的非SQL层级的优化(比如索引)。SQL没什么好优化的,少读几个列? 没必要;表连接少一点?(不用看SQL,看Hibernte就可以看出来).

3、使用自写的SQL,那就真需要“SQL跟踪”了,你不知道你哪一个地方写错了,这够没意义,而且够烦。

4、使用Hibernate不需要大牛,只要不盲从,回到基本面,从reference开始。
不了解的,不踏实的,新碰到的,那就做做试验--磨刀不误砍柴功

先到此为止,算是对楼上部分观点的回复



说的不错
   
0 请登录后投票
论坛首页 Java版 Hibernate

跳转论坛:
JavaEye推荐