mysql 存储过程 批量插入20W数据用时8s
需求:原先有一个张表t_member 存储用户数据,现有个功能需要存储很多用户数据,为了不让t_member表的column继续膨胀,选择添加一张关联表(t_bbs_behavior_data)
为了简化开发,因此需要把t_member的id关联上t_bbs_behavior_data的memberId
NO1.
测试数据20W 用时7-8s,不建议使用临时表然后定义变量使用while循环插入(用时太久了)
delimiter $$ drop PROCEDURE if exists saveBatchBehaviorData; -- 创建存储过程 create PROCEDURE saveBatchBehaviorData() BEGIN -- 声明变量,并初始化 declare i int default 0; declare member_id bigint(20); -- 定义游标,并将sql结果集 赋值到游标中 declare member cursor for select id from t_member; -- 声明当游标遍历完后将标志变量重置成某个值 declare CONTINUE HANDLER FOR NOT FOUND set i=1; -- 打开游标 open member; -- 将游标中的值赋值给变量 ,注意:变量名不要和返回的列名同名,变量顺序要和SQL结果列的顺序一直 fetch member into member_id; -- 关闭自动提交 set autocommit=0; -- while循环开始 while i<>1 do -- 插入 用户数据中心表 insert into t_bbs_behavior_data(`member_id`,`create_date`,`modify_date`) values (member_id,NOW(),NOW()); -- 将游标中的值再赋值给变量,供下次循环使用 fetch member into member_id; -- 当条件不满足时结束循环 end while; -- 提交 commit; -- 关闭游标 close member; -- 结束存储过程 end $$ delimiter ; -- 调用存储过程 call saveBatchBehaviorData();
NO2.
补丁(用来插入遗漏或者说正好有用户注册在执行之后,一般不会出现此情况)
delimiter $$ -- 删除原有的存储过程,与建表时类似 drop PROCEDURE if exists insertNotExistData; -- 创建存储过程 create PROCEDURE insertNotExistData(in memberId BIGINT(20)) -- 存储过程开始 begin IF NOT EXISTS(select id from t_bbs_behavior_data where member_id = memberId) THEN insert into t_bbs_behavior_data(`member_id`,`create_date`,`modify_date`) values (memberId,NOW(),NOW()); END IF; end $$ delimiter; -- 示例 call insertNotExistData(520);