Robbin只是在帮人解答测试Hibernate性能的问题,做技术的本身就是需要有严谨的态度,是错的就一针见血指出来,这样不好吗? 大家常在Jdon上,为什么?不就是要指出大家想法的错与对而得到提高吗?如果大家多从讨论技术的角度去看问题的话,相信大家就会有足够的包容力了。
Robbin只是在帮人解答测试Hibernate性能的问题,做技术的本身就是需要有严谨的态度,是错的就一针见血指出来,这样不好吗? 大家常在Jdon上,为什么?不就是要指出大家想法的错与对而得到提高吗?如果大家多从讨论技术的角度去看问题的话,相信大家就会有足够的包容力了。
但是不是错呢?抑或只是个人倾向呢?
我想大家都有自己的评判
我很欣赏Robbin帮助人的热情,不过我觉得他那样说话不是太合适
>>一次取30万条记录?你不妨查查任何数据库的官方手册,哪一个会推荐你这么做?如果是压力测试,那还情有可原,不过在这里,似乎不是吧,在工业环境下的性能测试,是必须符合实际情况的,你曾经做过的项目有一次取回30万条记录的功能?如果有,那我只能说I 服了 U<<
做性能测试不是我的本意,我也不认为我的测试结果有任何实际意义,这一点我已经n多次强调了,你看看前面的帖子,是楼主希望我把他的测试例子跑一遍,看看结果会有什么不同。但我觉得楼主的测试程序有些问题,所以就自己重新写了测试程序,但是是完全按照楼主给出的测试项目进行测试的。楼主的例子中的Create测试项目是Insert1000条,我就照样测试一下插入1000条,连数据都是照抄过来的。楼主的Read测试,楼主说他的表有56万条记录,他做的是查询'F',大概是1/3,将近20万条记录。所以我特意往数据库里面插入30万条记录,就是想看看在我的电脑上做同样的测试会有什么结果,和楼主的结果比较会有什么不同。你连这一点都不搞清楚,就随便发表意见,是不是太轻率了?
>>一上来就说人家程序有问题,又说人家测试没有用<<
没错,程序是有些问题,否则我就不会自己重新写测试程序了。我也确实认为楼主的测试没有实际意义(不是没有用,请你搞清楚!),因为实际应用中很少会出现插入上千条记录,查询几十万记录的情况,更多的情况是并发访问小数据量操作。当然我也从不认为我的测试结果有什么实际意义,这一点我也多次强调了。
>>虽然你说的没错,HIBERNATE 的总体性能较之相应的JDBC有所欠缺,但是请注意,JDBC本身是没有缓存的,而HIBERNATE对缓冲做了处理,所以从某种程度上来说,HIBERNATE的实用性能高于JDBC。<<
你搞搞清楚,我说过HIBERNATE 的总体性能较之相应的JDBC有所欠缺的话了吗?我的原话是说,精心编写的JDBC程序性能比任何ORM都要高!而且如果你注意到我的测试环境描述的话,你应该看到我特意关闭了Hibernate的连接池,所以没有PreparedStatement缓冲,另外我也没有使用JCS,所以没有ResultSet缓冲。我是特意要避免Hibernate的缓冲机制对我的测试结果产生影响,这一点我也在测试环境描述中强调了,否则的话,JDBC也可以使用连接池阿,JDBC也可以去使用JCS缓冲阿,那样的话,就比较不出来我原先要测试的结果了,变成了连接池缓冲性能的比拼了。所以深思熟虑再发言,别那么草率!!!
并且我已经在后面的帖子明明白白的强调了,由于MySQL的JDBC驱动的问题,测试结果全部作废,我们能够看出来的结论就是我最后说的那两点。
唯恐天下不乱
>>说句题外话,我也不认为此测试与彼得失有何根本得本质得改进。<<
我正是要按照楼主的测试项目照做一遍,如果我的测试内容和楼主的测试内容有本质不同,那不是我跑题了吗?
>>把所有都贴出来,声明测试得硬件软件配置,对于大家交流来说意义也不大。大家测得时候肯定都是在同一个环境下,大家只是关心问题所在和相对得测试得结果罢了。<<
我没有用过DB2,我的机器硬盘不够,也装不了Oracle9i,只好拿一个MySQL来测试测试,但实际上证明,用MySQL来测试得到的结果是极端不可信的,如果我不声明我的软硬件环境,那肯定会造成误导,你还认为声明软硬件环境是没有意义的吗?另外我的CPU主频太低,测试过程中经常是100%,Java进程和MySQL进程都要抢CPU资源,这样的话,由于CPU造成了瓶颈,也会很大程度上影响测试结果。
在这方面我们没法达成共识的话,不妨就此打住
一、“精心编写”的JDBC一定是性能最好的
实际上,不管CMP,Hibernate,JDO等等,所有的ORM都是对JDBC的封装,CMP则是一个重量级封装,JDO中度封装,Hibernate是轻量级的封装。从理论上来说,ORM永远也不可能比JDBC性能好。就像任何高级语言的运行性能永远也不会好过汇编语言一个道理。
对于Create和Update操作来说,由于普通的Java程序员未必会使用JDBC的Batch的功能,所以Hibernate会表现出超过JDBC的运行速度。
对于Read的操作来说,ORM普遍都会带有双层缓冲,即PrepreadStatement缓冲和ResultSet缓冲,而JDBC本身没有缓冲机制,在使用连接池的情况下,一些连接池将会提供PrepreadStatement缓冲,有的甚至提供ResultSet缓冲,但是普遍情况下,Java程序员一般都不会考虑到在写JDBC的时候优化缓冲,而且这样做也不太现实,所以在某些情况下,ORM会表现出超过JDBC的Read速度。
二、Hibernate List和Iterator方式的比较
这是我在测试中想要重点考察的方面,但是由于JDBC驱动问题,结果变的很不可信,不过仍然可以得到一些有用的结论。
Read操作包括两步:第一步是把数据库的数据取出,构造结果集,把数据放入到结果集中;第二步是遍历结果集,取每行数据。
List方式是1次性把所有的数据全部取到内存中,构造一个超大的结果集,主要的时间开销是这一步,这一步的时间开销要远远超过JDBC和Iterator方式下构造结果集的时间开销,并且内存开销也很惊人;而对结果集的遍历操作,速度则是非常的惊人(从上面的测试结果来看,30万记录的内存遍历不到100ms,由于这一步不受JDBC影响,因此结果可信)。因此,List方式适合于对结果集进行反复多次操作的情况,例如分页显示,往后往前遍历,跳到第一行,跳到最后一行等等。
Iterator方式只取记录id到内存中,并没有把所有数据取到内存中,因此构造结果集的时间开销很小,比JDBC和List方式都要少,并且内存开销也小很多。而对结果集的遍历的操作的时候,Iterator仍然要访问数据库,所有主要的时间开销都花在这里。因此,Iterator方式适合于只对结果集进行1次遍历操作的情况,并且Iterator方式特别适合于从超大结果集中取少量数据,这种情况Iterator性能非常好。另外Iterator方式可以利用JCS缓冲,在使用缓冲的情况下Iterator方式的遍历操作速度将不受数据库访问速度的影响,得到彻底的提升。
JDBC Read: 80ms
Hibernate List: 180ms
Hibernate Iterator: 3835ms
Hibernate Iterator JCS: 110ms
可见使用JCS以后,Iterator的性能有飞速提升,然而在这个测试中,不宜把JDBC和Hibernate的读取速度直接拿来对比,得出Hibernate的读性能不良的结论,原因还是因为JDBC驱动的问题。
这两天比较忙,没过来看
我刚看了所有的帖子,很高兴你做了这个测试
你说在实际应用中很少有一次插入1000条数据
实际情况是:我们的项目,会有一次插入3000条以上的数据的情况
至于查询,当然不是有一次查询出30万条数据来,但有一次要查询几万
条数据出来的情况。
所以我要测试一下HIBERNATE性能到底和直接用JDBC差多少,
如果相差不多,我就考虑用HIBERNATE做项目了。
另外,你做的那个测试,能不能把所有程序及相关XML等文件打一个包,
放到一个能下载的地方,我去下载来,在DB2上测试一下呢?
uu_snow@163.com
我用SQL Server2000测一下吧,看看M$的JDBCdriver如何,到时再交流。
http://www.j-netdirect.com
发布的时候准备改回MySql
除了SQL Server和MySql,windows平台下,robbin还有什么好的开源数据库介绍麽,主要是方便开发,性能到不太计较。
试过PostgreSql,在windows平台下始终没找到合用的版本