用hibernate的性能:插入很快,可查询为什么非常慢?????

03-08-19 uu_snow
              

我才开始用HIBERNATE,按照它的例子测试了一下性能,有点疑问!

我用的例子就是那个最最简单的cat的例子,只有一个cat的class,再没有其他

任何相关的类:

public class Cat {

private String id;

private String name;

private char sex;

private float weight;

......//get/set

}

然后我用hibernate操作这个cat类,写了一个插入DB的方法和查询的方法:

public void createCats(){

for(int i=0;i<1000;i++){

Cat princess = new Cat();

princess.setName("Princess"+i);

princess.setSex('F');

princess.setWeight(7.4f);

session.save(princess);

}

}

另一个查询的方法:

public void selectFemaleCats(){

String queryString = "select cat from Cat as cat where cat.sex = :sex";

Query query = session.createQuery(queryString);

query.setCharacter("sex", 'F');

for (Iterator it = query.iterate(); it.hasNext();) {

Cat cat = (Cat) it.next();

}

}

然后在另外一个方法里调用这两个方法:

public void test(){

long startTime=System.currentTimeMillis();

initHibernate();

System.out.println("-------------spare time 0:"+(System.currentTimeMillis()-startTime));

// Create some Cats

beginTransaction();

createCats();

endTransaction(true);

System.out.println("-------------spare time 1:"+(System.currentTimeMillis()-startTime));

// Select all Cats

beginTransaction();

selectFemaleCats();

endTransaction(false);

System.out.println("-------------spare time 2:"+(System.currentTimeMillis()-startTime));

}

其中,beginTransaction/endTransaction这两个方法很简单:

private void beginTransaction()

throws HibernateException {

session = sessionFactory.openSession();

transaction = session.beginTransaction();

}

private void endTransaction(boolean commit)

throws HibernateException {

if (commit) {

transaction.commit();

} else {

// Don't commit the transaction, can be faster for read-only operations

transaction.rollback();

}

session.close();

}

我运行这个如此简单的程序,看了一下它的效率:

[03-8-16 20:09:34:047 CST] 1cdb7652 SystemOut O -------------spare time 0:751

[03-8-16 20:09:39:345 CST] 1cdb7652 SystemOut O -------------spare time 1:6049

[03-8-16 20:10:25:752 CST] 1cdb7652 SystemOut O -------------spare time 2:52456

这个时间是我多次刷新页面以后一个大致稳定下来的时间,也就是说,

插入1000条数据,用HIBERNATE大致用6秒左右,查询大致在50秒左右!!!!!!!!

而我改成直接使用Statement(不是PreparedStatement),

插入1000条的时间一般是13秒,比用hibernate慢了一倍,但是,

查询的速度却保持在20秒左右,比用hibernate查询要快一倍多

请问,这是为什么呢?????????

              

1
yehs220
2003-08-19 11:53

iterate()当然慢了,它是先查询出id,然后每次next()的时候

再查询出数据。用list()试试!

robbin
2003-08-19 12:09

我还是那句老话,不要随便做这种性能测试,没有严格的测试环境,精心设计的测试用例,是得到任何有意义的结论的。

你的这个测试例子老实说,编译都通不过!我很怀疑你怎么测试的。

 for(int i=0;i<1000;i++){
Cat princess = new Cat();

 for (Iterator it = query.iterate(); it.hasNext();) {
Cat cat = (Cat) it.next();
}

你自己看看,这样的对象重复定义的错误,你如何能够编译通过,更不要说运行了。

bruce
2003-08-19 12:42

问一下Robbin,

我很想测一下用JDBC,Hibernate,CMP的性能,如CRUD, 但通过你的详尽贴子也知道有测试trap, 的确不是一个时间差就可以测的出来的,不过不知你了不了解Benchmarks等关于测试方面的,或者有什么好的测试工具推荐一下,我还是准备试比较合理的测一测它们的性能,先谢了。

robbin
2003-08-19 13:27

光是测时间是远远不够的,像JVM的CPU占用率,JVM的内存堆栈都需要测量,进行综合评定,我没有什么测试工具,不过我知道那些大公司内部有自己开发的专用测试软件。

其实这样的专业性能测试,不要说测试软件本身了,就是测试结果的评测报告都是需要花很多银子购买的。像Java程序这种不是直接在OS平台上运行,涉及到JVM本身的很多性能调节的测试,非专业公司是不能够做的。自己随便写几个程序,跑一下,比较一下运行时间长短就去议论软件的性能是非常有害处的。

JDBC,Hibernate和CMP的性能问题其实不需要测试,如果你能够足够了解它们的运行的原理和细节,性能是昭然若揭的,何必还做什么测试呢?只有性能接近,运行原理一样的软件才需要进行性能测试。

JDBC如果精心编写,程序员本身是JDBC高手,那么性能一定是最好的,任何ORM都比不上,就像汇编高手用汇编写的程序一定比任何高级语言性能都好的道理一样;

Hibernate是JDBC的轻量级封装,准确来说是PreparedStatement的封装,性能有稍微的损失,但是由于大多数程序员用JDBC的水平达不到那么高,就像上面的测试程序中之所以create的测试JDBC要慢一倍的原因就在于程序员不知道应该用Batch,所以写出来的JDBC程序比不上Hibernate

CMP其实就不用多说了,客户端的一次业务方法调用要经过多次RMI调用,好几层代理才能达到Bean里面我们编写的业务代码,再加上繁重的容器方法调用,性能不在一个数量级上。

17Go 1 2 3 4 ... 17 下一页