請教如何提高查詢系統的性能? 發表: 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