请教如何提高查询系统的性能?

我们图书馆图书查询系统,采用ORACLE+Tomcat,使用servlet+JavaBean通过Tomcat的连接池直接访问Oracle数据库做查询。

数据量大约为40万条图书信息,(图书信息采用类似xml的结构存储,每册图书的书名、作者等信息作为一个CLOB字段存储,由于不能直接建立索引,我们把其中的书名、作者等抽取出来存放在另外一个表中,这样查询时需要做两个表的连接查询),少量用户查询时还能及时响应,但是当同时查询的读者多,响应就特别慢。

请问各位大虾,我这个系统可以从哪些方面做性能改进??

做cache,把数据库里面的数据放到内存里面,这样可以加快查询速度

提高查询性能需要从几个方面提升。

首先你选择的是原始的Jsp/Servlet + JavaBeans结构,jsp/Servlet其实就是线程,当并发用户发生访问时,就是多线程了,因此,在你的程序中,首先避免多线程访问同一个资源,特别是Singleton方式,这个问题前面帖子已经大量讨论,这比如:本来是并行前进的,到了一个独木桥,必须串行前进,那么性能大大折扣了。


最好的方式是,一个对象为一个线程服务,并发10个线程就有10对象被访问,这样效率最高,但是同时注意,如果你这个Javabeans对象每次被访问都要new创建,有可能浪费性能,特别是Javabeans代码很多,功能很多时,那么使用pool,在系统启动时,就启动生成这些JavaBeans对象在内存中。

我上面说的这些javaBeans是功能性Javabeans,通过Pool提高功能性JavaBeans的性能。还有一种是数据javabeans,专门装载数据的,这部分使用Cache来提高。

EJB中的无态Session Bean底层已经有Pool支持,如果你将功能性JavaBeans的代码移植到Session Beans中实现,那么会提高并发用户的处理性能,使用SLSB的Local,关闭其网络性能损耗;关闭SLSB事务机制(如果不需要),这样将SLSB变成一个纯的Pool支持的特殊javaBeans了。

由于EJB中实体bean底层是有Cache支持的,因此可以用实体bean实现数据javaBeans的缓存,但是一般推荐,最好在Web层自己做一些缓存,这样离客户端最近,性能最好。

总之,性能问题其实是架构选择不慎带来的问题,在这个论坛看到了太多Jsp+JavaBeans的性能问题,为什么我们从系统一开始时,不选择可伸缩强大的EJB架构呢? 这样 ,在你的系统扩大时,你就不必为系统性能问题头疼,甚至性能问题导致了你的Jsp+JavaBeans系统失败。

EJB并不是万能的,什么系统都推荐EJB,这是典型的误人子弟
系统性能出现问题,应该先找出瓶颈所在,可用一些性能测试工具来做
本应用中,你为什么要把信息存成xml保存在blob中呢?这样读起来要解析,肯定性能有问题
如果你把这些信息都独立成一个个字段,再对数据库进行一些性能优化,应该就没有问题了。
40万条记录很少的

1:利用cache
2:修改sql,用oracle的特有的sql
3:不要轻易修改架构,ejb不是万能的,很讨厌那种动辄就谈ejb,绝对是误导。

对于ejb,我们曾经有过痛苦的经历,就是我们目前做的项目,几千万的大型集成软件,当初架构采用session bean,没有采用实体bean,但是目前提供的ejb容器在开发设计之初,总会测试出这样那样的问题(往往都是不可预知的错误,由于我们是财务项目,异常情况如果不能很好控制的话,其产品性能可想而知了)....,并且好多问题找供应商寻求解决,但是多方寻求结果未果的情况下,只好采用了比较成熟的struts(MVC)来进行开发。
对于查询的性能提高情况,个人理解有两个地方,一:前台与数据库之间的控制处理模式(JDBC或其他包装后处理程序)是至关重要的,这不仅仅影响查询的性能,同时还决定着系统的可扩充性和健壮性,提个很现实的问题:对于多数据库的支持,不仅要有通用性,还要有各自的相关优化措施才可以。
二:对于查询后的数据如何进行有效的处理,这也是影响查询性能的重要因素,如何进行高效准确的展示,当然包括一些中间驻留信息的保存、删除等处理,这些也可以规划为一种展示模式的设计。
以上两点为个人陋见,请大家一块讨论!!

40万的记录并不大,这样就不行了,肯定是设计 有问题.不明白你们为什么要用xml存储,然后再存成block字段?感觉象为了使用xml而用xml!

Javabean以及Singleton与性能关系不大,使用纯的javabean时,因为没有远程调用,性能比EJB要好,但是javabean中有synchronized关键字的另当别论,这个时候的Singleton成为了“独步桥”,性能会变得低下


import java.util.*;
import org.apache.log4j.*;

public class ThreadImpl extends Thread
{
public void run ()
{
BizTask.getInstance().run();
}

public static void main(String[] args)
{
for (int i = 0; i < 100; i++)
{
ThreadImpl t = new ThreadImpl ();
t.start();
}
}
}

class BizTask
{
private static final Category logger = Category.getInstance (BizTask.class);
private static BizTask instance = null;

private BizTask()
{
super();
}

public static BizTask getInstance()
{
if (instance == null)
instance = new BizTask();
return instance;
}

public synchronized void run ()
{
try
{
Thread.sleep(1000);
logger.debug(new Date());
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}


代码中BizTask是一个Singleton实例,但是
public synchronized void run ()方法的synchronized 将严重的影响性能,如果没有这个synchronized ,性能和不使用Singleton实例基本一致

一点浅见,请大家指正:
个人认为,Javabean以及Singleton与性能关系不大,使用纯的javabean时,因为没有远程调用,性能可能比EJB更好,但是javabean的方法中有synchronized关键字或者javabean调用了一个synchronized方法时的另当别论,这个时候的Singleton成为了“独步桥”,性能会变得低下
也就是说
Singleton + synchronized 将形成瓶颈
两者如果不在一起,不会形成瓶颈


import java.util.*;
import org.apache.log4j.*;

public class ThreadImpl extends Thread
{
public void run ()
{
BizTask.getInstance().run();
}

public static void main(String[] args)
{
for (int i = 0; i < 100; i++)
{
ThreadImpl t = new ThreadImpl ();
t.start();
}
}
}

class BizTask
{
private static final Category logger = Category.getInstance (BizTask.class);
private static BizTask instance = null;

private BizTask()
{
super();
}

public static BizTask getInstance()
{
if (instance == null)
instance = new BizTask();
return instance;
}

public synchronized void run ()
{
try
{
Thread.sleep(1000);
logger.debug(new Date());
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}

代码中BizTask是一个Singleton实例,但是
public synchronized void run ()方法的synchronized 将严重的影响性能,如果没有这个synchronized ,性能和不使用Singleton实例基本一致

个人认为:
使用EJB的好处是可以得到可以缩放的体系结构,业务实现可以部署在多个服务器中,形成分布式的体系结构。系统的容量可以动态的增加。
同时,使用javabean的时候,需要考虑线程安全,并且因为函数重入,在大量并发的时候,可能会出现内存空间不够,因为要动态的分配临时变量。
在小系统的情况下,javabean+jsp的性能应该高于ejb的系统

数据库
-------------------------------------------------------------
1、重新整理数据库的结构,尽量减少数据表之间的关联;

2、创建索引,增强查询的速度;

3、优化你的sql语句,有个人使用SQL语句N强,关联了3--4个表,中间用到了UNION,LIKE,IN,执行查询,4万条记录,时间为25秒;

应用服务器
--------------------------------------------------------------
1、适当的增加数据库连接池的连接,检查是否存在资源未释放的情况;

2、可以采用集群,增强并发访问量;

JavaBean
--------------------------------------------------------------
1、减去一些臃肿的代码,但是这样势必要造成代码的可读性差;

2、释放你没有关闭的资源,例如:IO资源、数据库连接等;

3、采用多线程;

提议:最好能够自己检查一下,找到出现性能瓶颈的真正所在:)

个人认为你的系统的瓶颈大部分是因为数据库设计不良造成的。

40多万条的数据用不到索引将是比较慢的,尤其当并发数很多的时候。
建议你:
首先对数据库做压力测试,找出几个典型的数据库操作。用测试工具进行压力测试。有条件的话可以用Loadrunner,qaload比较优秀的测试工具进行测试。这样可以清楚的看到你的数据库的最大负载,以及在并发数很高的情况的得系统响应速度。找出瓶颈,优化你的数据库设计。如果改优化的地方都优化了还是不信给就需要做数据库集群了。
再次;把一些频繁访问的数据放到内存中。尽量减少与数据库之间的操作,减少数据库压力。这样很容易提高系统响应速度,增加访问量

>>>>>> 把一些频繁访问的数据放到内存中。尽量减少与数据库之间的操作,减少数据库压力。这样很容易提高系统响应速度,增加访问量

有前提,应该是频繁访问的、不进行频繁修改的数据放在内存,同时希望搂主能够提供更多的信息,以帮助更好的解决问题:)感觉我正在盲人摸象

我个人认为 图书信息采用类似xml的结构存储 是影响性能的关键, 根本就没有用到数据库的处理能力, 而利用虚拟机去解析庞大的xml.

应该把这个改掉

>>我个人认为 图书信息采用类似xml的结构存储 是影响性能的关键, 根本就没有用到数据库的处理能力, 而利用虚拟机去解析庞大的xml.

也不一定,采用xml存储可能会比采用数据库存储的性能要好些,举个例子:
如果存储树形结构的数据到数据库中,可能需要进行遍历,当进行回朔查找上一级或者根节点的时候,是非常的消耗时间的,而采用xml存储结构,这样的查询往往很快,你可以试一下xquery;
而且国内现在存在倍多和timano公司的xml数据库,查询速度很快的,可以与关系型数据库相媲美;