有一个SQL单独执行1.8秒(从库里面取数1.2秒,往java的list里面放0.6秒)
※主要从两个表查询,每个表20万的数据量,查询结果集是1.1万 SQL逻辑有点复杂,将近180行
用java写测试,简单循环这个SQL,每次循环执行的时间和单次执行的时候差不多,到后面基本上每次执行速度都在提高一点
用java循环启动N个线程,每个线程干的事情就是执行一次SQL,在这种情况下,循环30次的话,大部分线程的SQL执行时间已经到了140秒以上了。
select 1 from dual
这样的sql,循环启动50个线程,最后面的线程执行是开始执行的六倍
而且启动的第一个线程,这样的sql都要执行1秒
单独执行的时候15毫秒就可以搞定
这是为什么呢? :oops:
[b]问题补充:[/b]
有一个SQL单独执行1.8秒(从库里面取数1.2秒,往java的list里面放0.6秒)
※主要从两个表查询,每个表20万的数据量,查询结果集是1.1万 SQL逻辑有点复杂,将近180行
用java写测试,简单循环这个SQL,每次循环执行的时间和单次执行的时候差不多,到后面基本上每次执行速度都在提高一点
用java循环启动N个线程,每个线程干的事情就是执行一次SQL,在这种情况下,循环30次的话,后面被执行的分线程的SQL执行时间已经到了30秒以上了。
select 1 from dual
这样的sql,循环启动50个线程,最后面的线程执行是开始执行的六倍
而且启动的第一个线程,这样的sql都要执行1秒
单独执行的时候15毫秒就可以搞定
这是为什么呢? :oops:
[b]问题补充:[/b]
错了,不是140秒,是后面被执行的线程已经40秒左右了 :oops:
[b]问题补充:[/b]
[code="java"]
R r = new R();
for(int i=0;i<50;i++){
Thread t = new Thread(r);
t.start();
}
public void run() {
try {
long a = System.currentTimeMillis();
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@172.23.9.150:1521:cleanperformance";
String userName = "cleanperformance";
String passWord = "cleanperformance";
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, userName, passWord);
String sql = "select 1 from dual";
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
List returnList = new ArrayList();
while (rs.next()) {
returnList.add(rs.getString(1));
}
rs.close();
pstmt.close();
conn.close();
long c = System.currentTimeMillis();
System.out.println("++++" + Thread.currentThread().getId()+":"+(c - a));
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
[/code]
就是上面这个时间了
[b]问题补充:[/b]
挂起时间当然是有啊!
但是我通常认为多线程的程序执行效率应该是高的。
现在多线程里面每个线程处理的时间居然比普通循环里面每次循环执行的时间
高出几个数量级,那要多线程还有什么意义吗?
[b]问题补充:[/b]
简单循环2000次,耗时间222763
循环启动2000个线程 耗时间214142
循环启动线程时的代码如下
[code="java"]
public class DbTest {
public static List tmpList = new ArrayList();
public static long _TM = 0;
public static void main(String[] args) throws Exception {
long startTime = System.currentTimeMillis();
R r = new R();
for(int i=0;i<2000;i++){
Thread t = new Thread(r);
t.start();
}
long endTime = System.currentTimeMillis();
Thread.sleep(232763);
System.out.println("$$$$$$$$$"+(_TM-startTime));
}
}
public void run() {
try {
long a = System.currentTimeMillis();
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@172.23.9.155:1521:MANIFESTO";
String userName = "MANIFESTO";
String passWord = "MANIFESTO";
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, userName, passWord);
String sql = "select 1 from dual";
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
List returnList = new ArrayList();
while (rs.next()) {
returnList.add(rs.getString(1));
}
rs.close();
pstmt.close();
conn.close();
DbTest.tmpList.add("aaa");
if (DbTest.tmpList.size() == 2000) {
DbTest._TM = System.currentTimeMillis();
}
long c = System.currentTimeMillis();
System.out.println("++++" + Thread.currentThread().getId()+":"+(c - a));
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
[/code]
[b]问题补充:[/b]
感觉单CPU情况下,多线程程序的执行效率没有太大提高
[b]问题补充:[/b]
两千次差这么点时间,我觉得可以忽略不计了. :lol:
一个采用了多线程技术的应用程序可以更好地利用系统资源。其主要优势在于充分利用了CPU的空闲时间片
多线程也要在多cpu的情况下才有更好的性能啊,不然就线程之间的切换和调度的时间就比单线程要多了多了,
具体情况具体分析
这个原因是cpu线程调度的问题吧。不是sql问题。。cpu的调度策略导致了这种情况。
首先我想确认一下,你说的“后面被执行的分线程的SQL执行时间已经到了30秒以上了”,你是否确定其他29个线程都已经结束,cpu只在运行这一个线程呢?这30秒可不是单个线程占用cpu的总时间,这个时间包含了调度,线程的等待时间和运行时间。简单的说,这30秒中线程不是一直执行sql,就像龟兔赛跑中的兔子,不是乌龟。这样说你可以理解么?
还是多线程的问题,楼主是不是认为当代码执行到long a = System.currentTimeMillis(); 之后就会一直执行到long c = System.currentTimeMillis(); 中间线程不被挂起呢?我说的是当执行run后,可能到11行,或者12行,或者13行。。。等等都可能被中断,在run()方法执行的时候都是会被其他线程抢占cpu的。这个时候被打断的线程只能等待重新获得cpu执行时间片。等待的时间也是时间。这样说可以理解不?
你存在理解误区啊。多线程效率高,不是说多线程中单个执行效率高,而是说整体效率。我举个例子,刚刚你这个程序如果改成是单线程的,即在一个线程中执行50次run()方法的内容,你在看看这50次的执行总时间和多线程的执行总时间谁的少呢
哦,我也陷入理解误区了。我觉得你的理解不错。应该是那样的