发表于: 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万71068ms75197ms31458ms40160ms
3000万2436107ms---1299507ms1369336ms
2亿---------9330877ms
可以看到,多线程的效率是单线程的两倍


可以验证昨天的结论:

1.  有索引的情况下,插入数据的速度比无索引慢

2.  插入的数据量越大,插入的速度就越慢


明天计划的事情:

1.  今天粗略的看了一遍github的用法,还有点模糊,明天试试看怎么用

2.  看了其他师兄任务1是怎么总结的,好像就是把所有问题解决,提交mybatis的两种用法的代码,感觉很快就能提交了



遇到的问题:

普通的println方法不能计算多线程的运行时间,参考了网上的一个CountDownLatch实例才写了出来



收获:

1.  学到了怎么使用多线程启动程序,如何计算多线程程序的运行时间

2.  github的基本用法浏览了一遍




返回列表 返回列表
评论

    分享到