1. 程式人生 > 資料庫 >mysql 迴圈批量插入的例項程式碼詳解

mysql 迴圈批量插入的例項程式碼詳解

背景

前幾天在MySql上做分頁時,看到有博文說使用 limit 0,10 方式分頁會有丟資料問題,有人又說不會,於是想自己測試一下。測試時沒有資料,便安裝了一個MySql,建了張表,在建了個while迴圈批量插入10W條測試資料的時候,執行時間之長無法忍受,便查資料找批量插入優化方法,這裡做個筆記。

資料結構

尋思著分頁時標準列分主鍵列、索引列、普通列3種場景,所以,測試表需要包含這3種場景,建表語法如下:

drop table if exists `test`.`t_model`;

Create table `test`.`t_model`( 
 `id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',`uid` bigint COMMENT '業務主鍵',`modelid` varchar(50) COMMENT '字元主鍵',`modelname` varchar(50) COMMENT '名稱',`desc` varchar(50) COMMENT '描述',primary key (`id`),UNIQUE index `uid_unique` (`uid`),key `modelid_index` (`modelid`) USING BTREE
) ENGINE=InnoDB charset=utf8 collate=utf8_bin;

為了方便操作,插入操作使用儲存過程通過while迴圈插入有序資料,未驗證其他操作方式或迴圈方式的效能。

執行過程

1、使用最簡單的方式直接迴圈單條插入1W條,語法如下:

drop procedure if exists my_procedure; 
delimiter //
create procedure my_procedure()
begin
 DECLARE n int DEFAULT 1;
 WHILE n < 10001 DO
 insert into t_model (uid,modelid,modelname,`desc`) value (n,CONCAT('id20170831',n),CONCAT('name','desc'); 
 set n = n + 1;
 END WHILE;
end
//               
delimiter ;

插入1W條資料,執行時間大概在6m7s,按照這個速度,要插入1000W級資料,估計要跑幾天。

2、於是,構思加個事務提交,是否能加快點效能呢?測試每1000條就commit一下,語法如下:

delimiter //
create procedure u_head_and_low_pro()
begin
 DECLARE n int DEFAULT 17541;
 WHILE n < 10001 DO
   insert into t_model (uid,'desc'); 
   set n = n + 1;
   if n % 1000 = 0 
   then
    commit;
   end if;
 END WHILE;
end
//
delimiter ;

執行時間 6 min 16 sec,與不加commit執行差別不大,看來,這種方式做批量插入,效能是很低的。

3、使用儲存過程生成批量插入語句執行批量插入插入1W條,語法如下:

drop procedure IF EXISTS u_head_and_low_pro;
delimiter $$
create procedure u_head_and_low_pro()
begin
 DECLARE n int DEFAULT 1;
 set @exesql = 'insert into t_model (uid,`desc`) values ';
 set @exedata = '';
 WHILE n < 10001 DO
 set @exedata = concat(@exedata,"(",n,","'id20170831","','","name","desc'",")");
 if n % 1000 = 0 
 then
  set @exesql = concat(@exesql,@exedata,";");
  prepare stmt from @exesql;
  execute stmt;
  DEALLOCATE prepare stmt;
  commit; 
  set @exesql = 'insert into t_model (uid,`desc`) values ';
  set @exedata = "";
 else
  set @exedata = concat(@exedata,',');
 end if;
 set n = n + 1;
 END WHILE;
end;$$ 
delimiter ;

執行時間 3.308s。

總結

批量插入時,使用insert的values批量方式插入,執行速度大大提升。

以上所述是小編給大家介紹的mysql 迴圈批量插入的例項程式碼詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回覆大家的。在此也非常感謝大家對我們網站的支援!
如果你覺得本文對你有幫助,歡迎轉載,煩請註明出處,謝謝!