倾家荡产求关于在Java类当中启用多线程查询oracle数据库的问题 ( 积分: 100 )

  • 主题发起人 主题发起人 xiaqiapeng
  • 开始时间 开始时间
X

xiaqiapeng

Unregistered / Unconfirmed
GUEST, unregistred user!
小弟在编一个查询数据库信息的类,原先的SQL语句是一个union查询,即把很多的select语句用union标识符连接起来,以便可以一次性从数据库检索到信息,但是由于数据量太大,union查询要很长时间才出结果,因而网页上面显示查询到的数据也要等待很长时间。于是我打算把每个查询放到一个线程中去跑,奇怪的是出来查询结果的总时间和用union查询出来的总时间差不多,我想用线程查询的话结果应该会快一点。不知道是不是代码写的有问题,还是oracle数据库会对从一台机子过来的查询请求进行排队。希望各位老大指点一二。代码如下:
try{
catchConn();
//得到数据库连接
outputList=new Vector();
outputArrayList=new ArrayList();
class Query implements Runnable {
private String innersql;
Thread t;
private Thread gett(){
return t;
}
public Query(String sqls){
innersql=sqls;
t=new Thread(this);
t.start();
}
public void run(){
try{
Statement innerstmt = dbConn.createStatement (java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,java.sql.ResultSet.CONCUR_READ_ONLY);
ResultSet innerrs = innerstmt.executeQuery(innersql);
while (innerrs.next()){
Hashtable outputInfoList = new Hashtable();
outputInfoList.put("name",innerrs.getString(1));
outputInfoList.put("area",innerrs.getString(2));
outputInfoList.put("count",new Integer(innerrs.getInt(3)));
System.out.println(innerrs.getString(1)+innerrs.getString(2)+"
"+innerrs.getString(3));
outputArrayList.add(outputInfoList);
}
innerrs.close();
innerstmt.close();
}
catch(Exception e1){
System.out.println("error");
}
}
}
Query a1=new Query(sqllist[0]);
//sqllist是7个长度的一维数组,每一个单位里面放一条查询语句,就是原来准备用union查询来合并的查询语句
Query a2=new Query(sqllist[1]);
Query a3=new Query(sqllist[2]);
Query a4=new Query(sqllist[3]);
Query a5=new Query(sqllist[4]);
Query a6=new Query(sqllist[5]);
Query a7=new Query(sqllist[6]);
try{
a1.gett().join();
a2.gett().join();
a3.gett().join();
a4.gett().join();
a5.gett().join();
a6.gett().join();
a7.gett().join();
}
catch(Exception e){}
接下来的语句不贴了,就是等到所有线程运行完毕后,把查询结果从ArrayList取出来,显示在网页上。
 
小弟在编一个查询数据库信息的类,原先的SQL语句是一个union查询,即把很多的select语句用union标识符连接起来,以便可以一次性从数据库检索到信息,但是由于数据量太大,union查询要很长时间才出结果,因而网页上面显示查询到的数据也要等待很长时间。于是我打算把每个查询放到一个线程中去跑,奇怪的是出来查询结果的总时间和用union查询出来的总时间差不多,我想用线程查询的话结果应该会快一点。不知道是不是代码写的有问题,还是oracle数据库会对从一台机子过来的查询请求进行排队。希望各位老大指点一二。代码如下:
try{
catchConn();
//得到数据库连接
outputList=new Vector();
outputArrayList=new ArrayList();
class Query implements Runnable {
private String innersql;
Thread t;
private Thread gett(){
return t;
}
public Query(String sqls){
innersql=sqls;
t=new Thread(this);
t.start();
}
public void run(){
try{
Statement innerstmt = dbConn.createStatement (java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,java.sql.ResultSet.CONCUR_READ_ONLY);
ResultSet innerrs = innerstmt.executeQuery(innersql);
while (innerrs.next()){
Hashtable outputInfoList = new Hashtable();
outputInfoList.put("name",innerrs.getString(1));
outputInfoList.put("area",innerrs.getString(2));
outputInfoList.put("count",new Integer(innerrs.getInt(3)));
System.out.println(innerrs.getString(1)+innerrs.getString(2)+"
"+innerrs.getString(3));
outputArrayList.add(outputInfoList);
}
innerrs.close();
innerstmt.close();
}
catch(Exception e1){
System.out.println("error");
}
}
}
Query a1=new Query(sqllist[0]);
//sqllist是7个长度的一维数组,每一个单位里面放一条查询语句,就是原来准备用union查询来合并的查询语句
Query a2=new Query(sqllist[1]);
Query a3=new Query(sqllist[2]);
Query a4=new Query(sqllist[3]);
Query a5=new Query(sqllist[4]);
Query a6=new Query(sqllist[5]);
Query a7=new Query(sqllist[6]);
try{
a1.gett().join();
a2.gett().join();
a3.gett().join();
a4.gett().join();
a5.gett().join();
a6.gett().join();
a7.gett().join();
}
catch(Exception e){}
接下来的语句不贴了,就是等到所有线程运行完毕后,把查询结果从ArrayList取出来,显示在网页上。
 
你用数据库连接池试试看?
 
to yanyandt2:
连接池我没用过,是不是把几个数据库连接放到一个vector里面,然后要用的时候取出一个去查询还是把几个查询线程放到一个vector里面,然后要用的时候拿出一个来查询?我有点忘了,这个对我来说有点难。
 
快来救人啊
 
今天总有人来解答了吧
 
啊,连接池就是在服务器端配置的管理数据库连接的,
welogic,tomcat里都能配置
 
晕倒!web请求方式是一应一答,发送HTTP请求,想要返回查询结果,必然是要等待的!!
这和你用不用线程有什么关系??再说了,servlet本身就支持多线程方式
 
我的意思是想把union查询里面的7个select语句拆开放到7个线程中去跑,按照理论,出来的查询结果应该比union查询出来的结果快,但是事与愿违,出来结果的时间和union查询出来的时间一样,我就感到不能理解.
 
你虽然用了7个线程,但是数据库连接还是一个,所以时间就一样了。
 
把你要连接的表先写个VIEW,然后在VIEW里查试试
 
wpx说的对,你可以建立视图,或者写存储过程,这样应该能快一些
而且,你查询用不用线程都是一样的。楼上的都说了,用连接池只能去掉连接数据库的开销,查询的时间是少不了得。
 
用多线程不会加快速度的,用union快
 
//用多线程不会加快速度的,用union快
严重表示同意,多线程会使速度更慢。
你把代码贴出来看看。
如果能不用union的话会快一些,用了也就是7次查询时间+1次连接数据库时间
 
to yanyandt2:
引用:"
来自:yanyandt2, 时间:2005-4-28 23:16:03, ID:3060605
你虽然用了7个线程,但是数据库连接还是一个,所以时间就一样了。 "
什么意思??如果多几个数据库连接,速度会快?!各位老大,我其实也是想试试多线程能否奏效,我刚在学,拜托![:D]
 
我知道union的时间和一次一次查的时间差不多,这个贴子想讨论的就是为何用7个线程查询出来的时间和union查询出来的时间差不多,请往这方面讨论.yanyandt2已经点到了一点,各位知情的能否再深入探讨一下,本人也是个学习JAVA的新手,想做深入的了解.[:D]
 
好了,说的再具体一点吧,这个贴子就是讨论本例中多线程的功效,我对我的union查询做了测试,运行一次要14秒(最近的一次竟然运行了36秒,数据库业务忙的时候),单个select子查询要2秒(有7个这样的子查询),我原先考虑的是我大概能在3-4秒出结果(不管我预测是否对还是错,因为具体的调度策略我不知道,但是也应该比14秒要快吧?!),结果出来的还是和union查询一样的时间,我就是这点不明白,大家讨论讨论吧,暂不考虑服务器端编程的问题,当然也欢迎大家谈[:D]
 
你用了多线程,其实线程是开在了java虚拟机中,而7个线程都用了一个数据库连接,
所以总的来说,你在数据库端的访问还是 1 个“通道”。
我是建议你每个线程使用不同的连接,再试试。
 
试了一下,还是老样(14秒),而且控制台输出是到14秒的时候一下子都出来的,而不是随着时间交替输出,感觉还是没有并发,以下是修改后的代码:
private Connection getConn(){
try {
Context initCtx = new InitialContext();
Context ctx = (Context) initCtx.lookup("java:comp/env");
//获取连接池对象
Object obj = (Object) ctx.lookup("jdbc/OracleDB");
//类型转换
javax.sql.DataSource ds = (javax.sql.DataSource) obj;
return ds.getConnection();
}
catch (Exception sqle) {
System.out.println("cannot connect db inside getConn");
return null;
}
}
class Query implements Runnable {
private String innersql;
Thread t;
private Thread gett(){
return t;
}
public Query(String sqls){
innersql=sqls;
t=new Thread(this);
t.start();
}
public void run(){
try{
Connection innerconn=getConn();
Statement innerstmt = innerconn.createStatement (java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,java.sql.ResultSet.CONCUR_READ_ONLY);
ResultSet innerrs = innerstmt.executeQuery(innersql);
while (innerrs.next()){
Hashtable outputInfoList = new Hashtable();
outputInfoList.put("name",innerrs.getString(1));
outputInfoList.put("area",innerrs.getString(2));
outputInfoList.put("count",new Integer(innerrs.getInt(3)));
System.out.println(innerrs.getString(1)+innerrs.getString(2)+"
"+innerrs.getString(3));
outputArrayList.add(outputInfoList);
}
innerrs.close();
innerstmt.close();
innerconn.close();

}
catch(Exception e1){
System.out.println("error");
}
}
}
以下是配置:
C:/Tomcat 4.1/conf/server.xml
<!-- Tomcat Venture Context -->
<Context path=&quot;/venture&quot;
docBase=&quot;venture&quot;
debug=&quot;0&quot;>
<Resource name=&quot;jdbc/OracleDB&quot;
auth=&quot;Container&quot;
type=&quot;javax.sql.DataSource&quot;/>
<ResourceParams name=&quot;jdbc/OracleDB&quot;>
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>oracle.jdbc.driver.OracleDriver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:oracle:thin:@130.37.0.1:1521:oranb</value>
</parameter>
<parameter>
<name>username</name>
<value>test</value>
</parameter>
<parameter>
<name>password</name>
<value>test</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>20</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>10</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>5000</value>
</parameter>
</ResourceParams>
</Context>
[:D]
 
后退
顶部