请教如何提高查询系统的性能? 发表: 2004年07月14日 20:22 回复

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

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

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

发表文章: 95
注册时间: 2004年06月14日 23:43
Re: 请教如何提高查询系统的性能? 发表: 2004年07月15日 19:22 回复
做cache,把数据库里面的数据放到内存里面,这样可以加快查询速度
banq

发表文章: 8048
注册时间: 2002年08月03日 17:08
Re: 请教如何提高查询系统的性能? 发表: 2004年07月19日 09:44 回复
提高查询性能需要从几个方面提升。

首先你选择的是原始的 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系统失败。







albert_qhd

发表文章: 8
注册时间: 2002年08月30日 15:30
Re: 请教如何提高查询系统的性能? 发表: 2004年07月19日 15:03 回复
EJB并不是万能的,什么系统都推荐EJB,这是典型的误人子弟
系统性能出现问题,应该先找出瓶颈所在,可用一些性能测试工具来做
本应用中,你为什么要把信息存成xml保存在blob中呢?这样读起来要解析,肯定性能有问题
如果你把这些信息都独立成一个个字段,再对数据库进行一些性能优化,应该就没有问题了。
40万条记录很少的
leexhwhy

发表文章: 2
注册时间: 2004年05月28日 09:19
Re: 请教如何提高查询系统的性能? 发表: 2004年07月20日 09:08 回复
1:利用cache
2:修改sql,用oracle的特有的sql
3:不要轻易修改架构,ejb不是万能的,很讨厌那种动辄就谈ejb,绝对是误导。
mikesun

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

发表文章: 238
注册时间: 2004年04月21日 15:02
Re: 请教如何提高查询系统的性能? 发表: 2004年07月20日 20:05 回复
40万的记录并不大,这样就不行了,肯定是设计 有问题.不明白你们为什么要用xml存储,然后再存成block字段?感觉象为了使用xml而用xml!
hb_nj

发表文章: 3
注册时间: 2004年07月20日 23:19
Re: 请教如何提高查询系统的性能? 发表: 2004年07月20日 23:27 回复
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实例基本一致
hb_nj

发表文章: 3
注册时间: 2004年07月20日 23:19
Re: 请教如何提高查询系统的性能? 发表: 2004年07月20日 23:36 回复
一点浅见,请大家指正:
个人认为,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的系统

chenzhongshan

发表文章: 13
注册时间: 2004年04月13日 14:31
Re: 请教如何提高查询系统的性能? 发表: 2004年07月21日 12:33 回复
数据库
-------------------------------------------------------------
1、重新整理数据库的结构,尽量减少数据表之间的关联;

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

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

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

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

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

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

3、采用多线程;

chenzhongshan

发表文章: 13
注册时间: 2004年04月13日 14:31
Re: 请教如何提高查询系统的性能? 发表: 2004年07月21日 12:35 回复
提议:最好能够自己检查一下,找到出现性能瓶颈的真正所在:)
starry

发表文章: 9
注册时间: 2002年11月11日 10:58
Re: 请教如何提高查询系统的性能? 发表: 2004年07月21日 15:11 回复
个人认为你的系统的瓶颈大部分是因为数据库设计不良造成的。

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

发表文章: 13
注册时间: 2004年04月13日 14:31
Re: 请教如何提高查询系统的性能? 发表: 2004年07月21日 15:41 回复
>>>>>> 把一些频繁访问的数据放到内存中。尽量减少与数据库之间的操作,减少数据库压力。这样很容易提高系统响应速度,增加访问量

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

发表文章: 4
注册时间: 2004年07月22日 17:40
Re: 请教如何提高查询系统的性能? 发表: 2004年07月22日 17:44 回复
我个人认为 图书信息采用类似xml的结构存储 是影响性能的关键, 根本就没有用到数据库的处理能力, 而利用虚拟机去解析庞大的xml.

应该把这个改掉
chenzhongshan

发表文章: 13
注册时间: 2004年04月13日 14:31
Re: 请教如何提高查询系统的性能? 发表: 2004年07月23日 10:33 回复
>>我个人认为 图书信息采用类似xml的结构存储 是影响性能的关键, 根本就没有用到数据库的处理能力, 而利用虚拟机去解析庞大的xml.

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

发表文章: 60
注册时间: 2003年07月17日 15:19
Re: 请教如何提高查询系统的性能? 发表: 2004年07月23日 10:48 回复
请问“banq”,你上面提到的“最好在Web层自己做一些缓存,这样离客户端最近,性能最好。”,请问大概是如何实现的?
cnwinds

发表文章: 4
注册时间: 2004年07月22日 17:40
Re: 请教如何提高查询系统的性能? 发表: 2004年07月23日 11:54 回复
> >>我个人认为 图书信息采用类似xml的结构存储
> 是影响性能的关键, 根本就没有用到数据库的处理能力,
> 而利用虚拟机去解析庞大的xml.
>
> 也不一定,采用xml存储可能会比采用数据库存储的性能要好?
> ,举个例子:
> 如果存储树形结构的数据到数据库中,可能需要进行遍历,当
> 谢厮凡檎疑弦患痘蛘吒诘愕氖焙颍欠浅5南氖奔涞模
> 而采用xml存储结构,这样的查询往往很快,你可以试一下xqu
> ry;
> 而且国内现在存在倍多和timano公司的xml数据库,查询速度?
> 快的,可以与关系型数据库相媲美;

原来新的数据库已经集成了对xml的支持了, 真是井底之蛙呀!
cnwinds

发表文章: 4
注册时间: 2004年07月22日 17:40
Re: 请教如何提高查询系统的性能? 发表: 2004年07月23日 11:57 回复
> 请问“banq”,你上面提到的“最好在Web层自己做一些缓存?
> 这样离客户端最近,性能最好。”,请问大概是如何实现的?

就是把常用的内容存放在内容中, 用时只要访问内存, 不需要访问数据库或业务层, 这样就快了.
zhangmingjing

发表文章: 60
注册时间: 2003年07月17日 15:19
Re: 请教如何提高查询系统的性能? 发表: 2004年07月23日 12:28 回复
> >
> 请问“banq”,你上面提到的“最好在Web层自己做一些缓存?>
> >
> 这样离客户端最近,性能最好。”,请问大概是如何实现的?
>
>
> 就是把常用的内容存放在内容中, 用时只要访问内存,
> 不需要访问数据库或业务层, 这样就快了.
原理我知道,我是指在Web层用什么技术实现,特别是采用群集的系统。
hb_nj

发表文章: 3
注册时间: 2004年07月20日 23:19
Re: 请教如何提高查询系统的性能? 发表: 2004年07月23日 23:39 回复
可以看看jboss cache或者oscache
hallguu

发表文章: 20
注册时间: 2003年07月23日 14:35
Re: 请教如何提高查询系统的性能? 发表: 2004年07月24日 16:33 回复
请试一试prevayler。

http://www.prevayler.org/wiki.jsp
mep

发表文章: 27
注册时间: 2003年10月14日 08:53
Re: 请教如何提高查询系统的性能? 发表: 2004年07月25日 10:53 回复
VLDB(Very Large Data Bases) conference 2003中有一篇论文,
Balancing Performance and Data Freshness in Web Database Servers
作者在这片文章中精彩的奉献了一种web和数据库应用对页面进行cache提高性能的方法。
VLDB是数据库领域最著名的学术会议之一。
mep

发表文章: 27
注册时间: 2003年10月14日 08:53
Re: 请教如何提高查询系统的性能? 发表: 2004年07月25日 10:55 回复
忘了链接:
http://wwwdb.informatik.uni-rostock.de/vldb2003/papers/S13P01.pdf
anonymous

发表文章: 0
注册时间:
Re: 请教如何提高查询系统的性能? 发表: 2004年07月25日 13:38 回复
> > 就是把常用的内容存放在内容中, 用时只要访问内存,
> > 不需要访问数据库或业务层, 这样就快了.


胡扯! 图书馆这样的数据库查询的离散性很大,加上缓存,只会导致速度更慢,占内存更大!
这是典型的数据库设计问题导致的,还是老老实实抓取 SQL 语句,放到数据库中仔细的 Explain 吧!

chenzhongshan

发表文章: 13
注册时间: 2004年04月13日 14:31
Re: 请教如何提高查询系统的性能? 发表: 2004年07月26日 10:57 回复
> 最好在Web层自己做一些缓存,
> 这样离客户端最近,性能最好

这样的话,是可以解决一些性能问题的;但是这样必将带来一些不必要的麻烦,比如数据同步;
zhangmingjing

发表文章: 60
注册时间: 2003年07月17日 15:19
Re: 请教如何提高查询系统的性能? 发表: 2004年07月26日 13:20 回复
如果我没有理解错的话,可能就是指在JavaBeans里自己做缓存。
asdlcj

发表文章: 22
注册时间: 2004年03月19日 23:42
Re: 请教如何提高查询系统的性能? 发表: 2004年07月26日 14:13 回复
web层的缓存其实就是类似jive处理缓存的技术类似

用一些容器类来放数据!直接放在内存中!
anonymous

发表文章: 0
注册时间:
Re: 请教如何提高查询系统的性能? 发表: 2004年07月26日 20:36 回复
问题的关键是:
你要缓存什么东西呢?以及要占用多大的内存
windjp

发表文章: 16
注册时间: 2004年02月06日 17:34
Re: 请教如何提高查询系统的性能? 发表: 2004年08月06日 10:52 回复
大家少谈一点设计模式好吗?设计模式不是用来解决所有的问题的。
你的问题最重要的是数据库结构的设计上,还有sql的优化。再说一个图书信息系统需要将信息转换成xml村成blob吗?不理解。
最后慎用cache,除非你对数据一致、事务等问题很清楚。
banq

发表文章: 8048
注册时间: 2002年08月03日 17:08
Re: 请教如何提高查询系统的性能? 发表: 2004年08月06日 15:44 回复
JdonSD框架使用缓存提升性能,可见测试报告:
http://www.jdon.com/product/performance.htm