mysql 循環(huán)批量插入的實(shí)例代碼詳解
背景
前幾天在MySql上做分頁(yè)時(shí),看到有博文說(shuō)使用 limit 0,10 方式分頁(yè)會(huì)有丟數(shù)據(jù)問(wèn)題,有人又說(shuō)不會(huì),于是想自己測(cè)試一下。測(cè)試時(shí)沒(méi)有數(shù)據(jù),便安裝了一個(gè)MySql,建了張表,在建了個(gè)while循環(huán)批量插入10W條測(cè)試數(shù)據(jù)的時(shí)候,執(zhí)行時(shí)間之長(zhǎng)無(wú)法忍受,便查資料找批量插入優(yōu)化方法,這里做個(gè)筆記。
數(shù)據(jù)結(jié)構(gòu)
尋思著分頁(yè)時(shí)標(biāo)準(zhǔn)列分主鍵列、索引列、普通列3種場(chǎng)景,所以,測(cè)試表需要包含這3種場(chǎng)景,建表語(yǔ)法如下:
drop table if exists `test`.`t_model`; Create table `test`.`t_model`( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增主鍵', `uid` bigint COMMENT '業(yè)務(wù)主鍵', `modelid` varchar(50) COMMENT '字符主鍵', `modelname` varchar(50) COMMENT '名稱(chēng)', `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;
為了方便操作,插入操作使用存儲(chǔ)過(guò)程通過(guò)while循環(huán)插入有序數(shù)據(jù),未驗(yàn)證其他操作方式或循環(huán)方式的性能。
執(zhí)行過(guò)程
1、使用最簡(jiǎn)單的方式直接循環(huán)單條插入1W條,語(yǔ)法如下:
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',n),'desc'); set n = n + 1; END WHILE; end // delimiter ;
插入1W條數(shù)據(jù),執(zhí)行時(shí)間大概在6m7s,按照這個(gè)速度,要插入1000W級(jí)數(shù)據(jù),估計(jì)要跑幾天。
2、于是,構(gòu)思加個(gè)事務(wù)提交,是否能加快點(diǎn)性能呢?測(cè)試每1000條就commit一下,語(yǔ)法如下:
delimiter // create procedure u_head_and_low_pro() begin DECLARE n int DEFAULT 17541; WHILE n < 10001 DO insert into t_model (uid,modelid,modelname,`desc`) value (n,CONCAT('id20170831',n),CONCAT('name',n),'desc'); set n = n + 1; if n % 1000 = 0 then commit; end if; END WHILE; end // delimiter ;
執(zhí)行時(shí)間 6 min 16 sec,與不加commit執(zhí)行差別不大,看來(lái),這種方式做批量插入,性能是很低的。
3、使用存儲(chǔ)過(guò)程生成批量插入語(yǔ)句執(zhí)行批量插入插入1W條,語(yǔ)法如下:
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,modelid,modelname,`desc`) values '; set @exedata = ''; WHILE n < 10001 DO set @exedata = concat(@exedata,"(",n,",","'id20170831",n,"','","name",n,"','","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,modelid,modelname,`desc`) values '; set @exedata = ""; else set @exedata = concat(@exedata,','); end if; set n = n + 1; END WHILE; end;$$ delimiter ;
執(zhí)行時(shí)間 3.308s。
總結(jié)
批量插入時(shí),使用insert的values批量方式插入,執(zhí)行速度大大提升。
以上所述是小編給大家介紹的mysql 循環(huán)批量插入的實(shí)例代碼詳解,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
MySQL學(xué)習(xí)第四天 Windows 64位系統(tǒng)下使用MySQL
MySQL學(xué)習(xí)第四天教大家如何在Windows 64位下使用MySQL,即使用命令行方式完成操作MySQL服務(wù),感興趣的小伙伴們可以參考一下2016-05-05mysql 8.0.18各版本安裝及安裝中出現(xiàn)的問(wèn)題(精華總結(jié))
這篇文章主要介紹了mysql 8.0.18各版本安裝及安裝中出現(xiàn)的問(wèn)題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12MySQL數(shù)據(jù)庫(kù)高級(jí)數(shù)據(jù)操作之新增數(shù)據(jù)
這篇文章主要介紹了MySQL數(shù)據(jù)庫(kù)高級(jí)數(shù)據(jù)操作之新增數(shù)據(jù),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-06-06解決mysql ERROR 1045 (28000)-- Access denied for user問(wèn)題
這篇文章主要介紹了mysql ERROR 1045 (28000)-- Access denied for user解決方法,需要的朋友可以參考下2018-03-03IOS 數(shù)據(jù)庫(kù)升級(jí)數(shù)據(jù)遷移的實(shí)例詳解
這篇文章主要介紹了IOS 數(shù)據(jù)庫(kù)升級(jí)數(shù)據(jù)遷移的實(shí)例詳解的相關(guān)資料,這里提供實(shí)例幫助大家解決數(shù)據(jù)庫(kù)升級(jí)及數(shù)據(jù)遷移的問(wèn)題,需要的朋友可以參考下2017-07-07MySQL Limit性能優(yōu)化及分頁(yè)數(shù)據(jù)性能優(yōu)化詳解
今天小編就為大家分享一篇關(guān)于MySQL Limit性能優(yōu)化及分頁(yè)數(shù)據(jù)性能優(yōu)化詳解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03