发表于: 2017-07-16 22:57:01
1 1317
今天完成的事情:
28.数据库里插入100万条数据,对比建索引和不建索引的效率查别。再插入3000万条数据,然后是2亿条,别说话,用心去感受数据库的性能。
今天看到罗泽应师兄说多线程插入数据的速度会快点,重构了昨天的代码
分10个线程,每个线程插入2000w的数据
public class ThreadInsertTest2 {
private int nThread;
private CountDownLatch startGate;
private CountDownLatch endGate;
public static void main(String[] args) {
int nThread = 10;
CountDownLatch startGate = new CountDownLatch(1);
CountDownLatch endGate = new CountDownLatch(nThread);
new ThreadInsertTest2(nThread,startGate,endGate).start();
}
public void start() {
for (int i=0;i<nThread;i++) {
Thread thread = new Thread(new insert());
thread.start();
}
long startTime = System.currentTimeMillis();
startGate.countDown();
try {
endGate.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("插入2亿条数据用时: " + (endTime- startTime) + "ms");
}
public ThreadInsertTest2(int nThread, CountDownLatch startGate, CountDownLatch endGate) {
this.nThread = nThread;
this.startGate = startGate;
this.endGate = endGate;
}
class insert implements Runnable {
public void run() {
try {
startGate.await();
Connection conn = null;
PreparedStatement ps = null;
String sql = "INSERT INTO user (user_name,password,sex) VALUE ('username','password',1)";
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/user?characterEncoding=utf8&useSSL=true&useServerPrepStmts=false&rewriteBatchedStatements=true", "yourusername", "yourpassword");
conn.setAutoCommit(false);
ps = conn.prepareStatement(sql);
long start = System.currentTimeMillis();
for (int i = 0; i < 20000000; i++) {
ps.addBatch(sql);
if (i % 100000 == 0) {
ps.executeBatch(); //每十万条数据提交一次,以防内存溢出
conn.commit();
}
}
ps.executeBatch(); //最后再提交一次,若插入数据不是整数也没有关系
conn.commit();
long end = System.currentTimeMillis();
System.out.println("单个线程插入数据所需时间:" + (end - start) + "ms");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (ps != null) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
endGate.countDown();
}
}
}
}
插入完成:
数据库查询:
总体测试结果:
无索引 | 有索引 | 多线程无索引 | 多线程有索引 | |
100万 | 71068ms | 75197ms | 31458ms | 40160ms |
3000万 | 2436107ms | --- | 1299507ms | 1369336ms |
2亿 | --- | --- | --- | 9330877ms |
可以验证昨天的结论:
1. 有索引的情况下,插入数据的速度比无索引慢
2. 插入的数据量越大,插入的速度就越慢
明天计划的事情:
1. 今天粗略的看了一遍github的用法,还有点模糊,明天试试看怎么用
2. 看了其他师兄任务1是怎么总结的,好像就是把所有问题解决,提交mybatis的两种用法的代码,感觉很快就能提交了
遇到的问题:
普通的println方法不能计算多线程的运行时间,参考了网上的一个CountDownLatch实例才写了出来
收获:
1. 学到了怎么使用多线程启动程序,如何计算多线程程序的运行时间
2. github的基本用法浏览了一遍
评论