MySQL:JDBC批量插入資料的效率

長不大的學生發表於2021-08-16

平時使用mysql插入、查詢資料都沒有注意過效率,今天在for迴圈中使用JDBC插入1000條資料居然等待了一會兒

就來探索一下JDBC的批量插入語句對效率的提高

首先進行建表

create table `user1`(
    `id` int primary key auto_increment,
    `phoneNumber` int not null  ,
    `indentity` int not null  ,
    `address` varchar(100),
    index (id,phoneNumber,indentity)
)engine =innoDB default charset = utf8mb4;
  • 這裡使用了一個組合索引,會降低插入資料的效率,應該就是我插入1000條資料都會感覺慢的主要原因
  • 儲存引擎是innoDB,據說MyISAM插入資料會更快

JDBC運算元據庫

使用的是MySql8.0

       Class.forName("com.mysql.cj.jdbc.Driver");
            //不需要建立 SSL 連線,需要顯示關閉。
            //allowPublicKeyRetrieval=true 允許客戶端從伺服器獲取公鑰。
            //時區為UTC
            String dburl = "jdbc:mysql://localhost:3306/myTest?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";
            String username = "root";
            String password = "123456";
            Connection connection = DriverManager.getConnection(dburl,username,password);

 

PreparedStatement的批量插入

        String sql = "insert into `user1`(`phoneNumber`, `indentity`, `address`) values (?,?,?)";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            Date date = new Date();
            System.out.println(date.toString());

            for (int i = 1000; i < 2000; i++) {
                preparedStatement.setInt(1,i+2);
                preparedStatement.setInt(2,i+101);
                preparedStatement.setString(3,"dizhi");
                preparedStatement.addBatch();
            }
            preparedStatement.executeBatch();

執行結果顯示出,插入1000條資料只用了16秒

 

 

for迴圈暴力插入資料

            Date date = new Date();
            System.out.println(date.toString());

            for (int i = 4000; i < 5000; i++) {
                preparedStatement.setInt(1,i+2);
                preparedStatement.setInt(2,i+101);
                preparedStatement.setString(3,"dizhi");
                preparedStatement.execute();
            }
            Date date1 = new Date();
            System.out.println(date1.toString());            

執行結果顯示用了17秒,用for迴圈插入和批量插入用的時間差距並不大的,這明顯有問題,所以進行第二次批量插入查詢

 

 

然後進行第二次批量插入實驗(其實是先第二次批量插入再用的暴力for)

           Date date = new Date();
            System.out.println(date.toString());
//
            for (int i = 3000; i < 4000; i++) {
                preparedStatement.setInt(1,i+2);
                preparedStatement.setInt(2,i+101);
                preparedStatement.setString(3,"dizhi");
                preparedStatement.addBatch();
            }
            Date date1 = new Date();
            System.out.println(date1.toString());            

 

結果很神奇,第二次批量插入立即完成,完全沒有延遲

具體原因還需要多多百度,我猜測是MySQL快取的作用,省去了很多互動過程,減少了網路傳輸

 

第三次批量插入資料

現在距離第二次已經過去了很長時間,這次測試是想看看MySQL快取還在不在

            Date date = new Date();
            System.out.println(date.toString());
            for (int i = 5000; i < 6000; i++) {
                preparedStatement.setInt(1,i+2);
                preparedStatement.setInt(2,i+101);
                preparedStatement.setString(3,"dizhi");
                preparedStatement.addBatch();
            }
            preparedStatement.executeBatch();
            Date date1 = new Date();
            System.out.println(date1.toString());     

顯然,又是16秒,看來是時間過去太久了

總的來說,MySQL是真個神奇的玩意

 

相關文章