今天在java上测试mysql MYISAM表的插入性能,,发现单线程插入比多线程还要慢,一直认为MYISAM表是表级锁,所以应该单线程快(可以省略线程切换等花销),但是测下来的结果是4线程的插入性能比单线程要快一倍多,,,求大神解释。
下面是测试代码:package Task;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.sina.sae.util.SaeUserInfo;class InsertThread extends Thread{
private Connection con;
private Statement statement;

public void Connect() throws ClassNotFoundException, SQLException{
String URL="jdbc:mysql://127.0.0.1:3306/weibo";//使用主库的域名
String username="wanghan";
String password="wanghan";
String driver="com.mysql.jdbc.Driver";
Class.forName(driver);    // 加载驱动程序
con=DriverManager.getConnection(URL,username,password);
if(!con.isClosed()){
System.out.println("Succeeded connecting to the Database!");     //验证是否连接成功
}
statement = con.createStatement();
con.setAutoCommit(false);
}

public void run(){
String sql = "insert into test (data) values ('111')";
for(int i=0;i<25000;++i){
try {
int rs = statement.executeUpdate(sql);
con.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}class  MySQLTest{
public void insert() throws ClassNotFoundException, SQLException, InterruptedException{
long startTime=System.currentTimeMillis();
Vector<InsertThread> listInsertThread = new Vector<InsertThread>();
for(int i=0;i<4;++i){
listInsertThread.add(new InsertThread());
}
for(int i=0;i<4;++i){
listInsertThread.get(i).Connect();
listInsertThread.get(i).start();
}
for(int i=0;i<4;++i){
listInsertThread.get(i).join();
}
long endTime=System.currentTimeMillis(); //获取结束时间  
 System.out.println("程序运行时间: "+(endTime-startTime)+"ms");   
//System.out.println(username);
//String driver="com.mysql.jdbc.Driver";
}
}public class TaskRun {
public static void main(String args[]) throws ClassNotFoundException, SQLException, InterruptedException{
// BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>();
// ThreadPoolExecutor threadPool = new ThreadPoolExecutor(4, 4, 0, TimeUnit.DAYS, taskQueue);
// threadPool.execute(new StockFetchTask());
//Thread.sleep(500);
//System.out.println("add");
MySQLTest mysqlTest = new MySQLTest();
mysqlTest.insert();
}
}

解决方案 »

  1.   

    我想大多数的时间都花费在Connect()方法的数据库连接上,建议只开一次,然后测试线程。读写完毕之后再释放资源。
      

  2.   


    代码里面每个线程只connect了一次数据库~~~在run函数里都是执行sql
      

  3.   

    MYISAM是表级锁,所谓的commit不可能是批量的提交的,他本身就不支持事务,1楼已经解释了这方面的原因,而4线程低并发肯定高于单线程,他连接数据库的次数明显比单线程少很多。