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

  • 主题发起人 主题发起人 xiaqiapeng
  • 开始时间 开始时间
我只修改了线程类,加了个得到数据库连接的方法,就是每次建立一个新的数据库连接,先试试,也不搞复杂的连接池了,其他和原来一样。[:D]
 
SQL语句如下;
select 'a887',area,count(*) from venture.userinfo where (yhlb='CA' or yhlb='CE') and logintype<>'KH121' and to_char(logdt,'YYYYMMDD') between '19900101' and '20050327' group by area
union
select 'b112',area,count(*) from venture.userinfo where yhlb='KG' and logintype<>'KH120' and to_char(logdt,'YYYYMMDD') between '19900101' and '20050327' group by area
union
select 'c174',area,count(*) from venture.userinfo where yhlb='DG' and logintype<>'KH113' and to_char(logdt,'YYYYMMDD') between '19900101' and '20050327' group by area
union
select 'd027',area,count(*) from venture.userinfo where (yhlb='XH' or yhlb='XE') and logintype<>'KH119' and to_char(logdt,'YYYYMMDD') between '19900101' and '20050327' group by area
union
select 'e034',area,count(*) from venture.userinfo where yhlb='ZH' and logintype<>'KH120' and to_char(logdt,'YYYYMMDD') between '19900101' and '20050327' group by area
union
select 'f103',area,count(*) from venture.userinfo where yhlb='KG' and yhlb2='LYH' and logintype<>'KH120' and to_char(logdt,'YYYYMMDD') between '19900101' and '20050327' group by area
union
select 'g010',area,count(*) from venture.userinfo where yhlb='XM' and yhlb2='LYH' and logintype<>'KH119' and to_char(logdt,'YYYYMMDD') between '19900101' and '20050327' group by area;
[:D]
 
你可以在 run 方法里打印出执行时间,
看看是 每个线程轮流执行还是按顺序执行。
 
我在上班,诶,最后一天
 
试过了,没有交替输出,是到最后一刻一下子输出的,感觉好象是堵住了,最后爆发,就象洪水.
 
以下是CSDN上vincege(热得快)的答复:
回复人: vincege(热得快) ( ) 信誉:100 2005-4-30 15:40:05 得分: 0

怎么就跟你说不明白呢?举例来说吧。
每个子查询2秒=0.5秒建立连接+1.5秒进行查询。
1.5秒进行查询这个事件是一个大计算量任务,cpu没有空闲(不能切换到其它线程或切换后也没有意义)。
7个连接的最好情况是0.5+1.5*7=11秒,这是建立在所有建立连接的工作并行完成的前提下。
多线程在进行多个查询时(多个1.5秒的计算任务可能会有并行,但由于是大计算量任务并行也无法更高的提高cpu利用率来提高速度,而提高cpu利用率是多线程提速的途径)时可能有些优势,但在多次建立连接的开销又把它抹平了。
下面是我的答复:
回复人: xiaqiapeng(kaka) ( ) 信誉:100 2005-5-1 12:19:16 得分: 0
你讲的有道理,但是另外我也感到疑惑,因为我有测试过,比如一个union查询要24秒,我将两个union查询在两台机子上同时并发运行,结果他们出来查询结果的时间同是36秒,就是说我如果顺序查询的话要2个24秒,但是我同时执行的话只要36秒,节省了24*2-36=12秒.我想oracle数据库应该是会并发来运行用户查询的(通过某种特殊的调度策略),至少不是顺序的.
回复人: xiaqiapeng(kaka) ( ) 信誉:100 2005-05-01 12:53:00 得分: 0
我现在的情况就是疑惑.转贴O'REILLY出版的Java线程(第二版)中的一段话印证vincege(热得快)的观点.
假设一个计算服务器(CalcServer)对于每一个客户的连接都会进行某种复杂的分析计算工作;同样假设这个计算对于每一个客户要耗时5秒钟.当有五个用户同时连接到服务器上时,CalcServer就会创建五个单独的线程.如果这些线程是分时间片的,它们要使用25秒来完成所有的计算工作,因为这五个线程是被平等对待的.我们可以认为这五个线程都是大概在25秒后才完成它们各自的计算任务的.因此每一个客户都是在25秒后才得到其计算结果的.如果我们的CalcServer不使用循环调度算法,就会有不同的结果:客户还是在同一时刻连接上服务器,但是某个客户(可能是任意选择的一个)得到了完成其计算工作的机会;因此第一个客户在第5秒就得到了结果,而不是25秒.接着第二个客户的计算开始了;第二个客户会在第10秒得到结果,依此类推.只有第5个客户会在第25秒得到运算结果.
到底上面的哪个调度机制更合理些?答案依赖于在这5秒钟内服务器的行为.如果仅仅是输出一个结果,很显然非时间片调度算法更公平:平均而言,每一个客户要等待15秒来得到结果而不是时间片算法中的25秒.但是如果服务器在每一秒钟的计算中都会给客户一个结果的话,则时间片算法更公平:每一个客户在5秒钟后都有一个结果,而在非时间片算法中,第五个客户到了第21秒钟才会得到第一个结果。
换句话说,对于“显示中间结果”这样的要求而言,循环调度算法提供了公平的结果。但是如果我们所关心的是最终的计算答案,那么在一个单CPU的机器上循环调度算法并不合适:即使在最好的情况下,它也没有体现出什么优越性,而对于CalcServer这样的例子而言,它实际上是降低了系统的吞吐量。
对于一个有多个CPU的系统而言,情况就更复杂了。如果在一个有四个CPU的机器上运行五个线程,假设系统不是使用循环调度算法,客户得到结果的平均时间是6秒钟:头四个将在第5秒钟得到结果,而最后一个会在第10秒得到结果。另一方面,如果使用循环调度算法,平均响应时间是6.2秒。但是,每一个回答的时间都非常的接近于6.2秒钟:实际上,我们可以认为每一个客户都会在6.2秒钟后得到结果。因此,尽管循环调度算法的平均计算时间稍微多一点,但是它提供了更高的公平性。而且在这个例子中,如果我们最关心的是何时得到这五个线程的最终结果,则循环调度算法更快:6.2秒对10秒。
------------------------------------------------------------------------------
我现在在想的是,Oracle是否有对查询线程采取特殊的调度策略,就好像类似于上面所说的多个CPU的情况.即Oracle仿真出类似于多个CPU在进行处理.这样的话循环调度算法对于得到最终结果来说是占优势的.就如同上面的6.2秒对10秒.也应证了我之前的测试结果.此外,查询线程的调度可以让数据库进行,就好象Java当中绿色线程是让Java虚拟机调度,而不是由运行虚拟机的操作系统进行调度.另外一个疑问是,Java线程是否屏蔽了数据库采取的调度策略,而严格按照分时间片来计算,导致最终结果都是在最后一起出来.就象我最初提出的情况.
 
今天有人来解答吗[:(]
 
我感觉瓶颈不在java这端,而在oracle的处理能力上。
建议你对sql语句进行分析,察看explain plan. 运行单个的sql和union的sql进行时间对比。
 
不管你前端用什么机制,真正完成处理的都是后台。你的消耗不是取数据的消耗,因为你查询出的数据总量是一样(不管你用什么方式),时间开销都在后台查询。试想假设你某个查询表有一个大对象数据。我们都查这样一张表7次用线程查询汇总,和一次执行6个union 此表的SQL查询。时间应该是一样的。很可能7个线程查同一线表时,oracle本身是单线程处理。因为上一个查询没有释放锁,下一个查询只有等待了。
 
多人接受答案了。
 
后退
顶部