项目要求单表支持上亿数据量,需要在mysql中构建数据进行测试,最后采用存储过程方案,记录一下脚本:
# 关闭binlog 防止产生大量log
set sql_log_bin=0;
DROP PROCEDURE
IF
EXISTS `add_data`;
# 将结尾符从分号临时换为 $$
DELIMITER $$
CREATE PROCEDURE `add_data` ( pos_begin INT, pos_end INT ) BEGIN
DECLARE i INT;
SET i = pos_begin;
SET AUTOCOMMIT = 0;
WHILE
i >= pos_begin && i <= pos_end DO
INSERT INTO `localdeployment_server`.`corpus_details_16` ( `source_content`, `source_content_md5`, `source_language_id`, `target_content`, `target_content_md5`, `target_language_id`, `realm_code`, `corpus_score`, `create_time`, `create_name`, `is_delete` )
VALUES
( '测试数据', '145314895749100ae8306079519b3393', 1, CONCAT('It\'s a cold winter AA.', i) , i, 2, 0, 0.842105, '2022-12-29 13:34:33', 'tianfn', 0 );
COMMIT;
SET i = i + 1;
END WHILE;
END $$
DELIMITER;
CALL add_data ( 0, 1000000 );
我是docker-compose中的数据库,所以选择后台运行的命令:
docker-compose exec db mysql -u root -p123456 localdeployment_server -e "CALL add_data ( 0,100000000)";
如果一开始没有关binlog ,可以在插入后删除:
show master status;
根据file字段进行删除:
purge master logs to "binlog.000048";
找到了更快得的方案:
-- 客户端连接服务端时,加上参数 -–local-infile
mysql –-local-infile -u root -p
-- 设置全局参数local_infile为1,开启从本地加载文件导入数据的开关
set global local_infile = 1;
-- 执行load指令将准备好的数据,加载到表结构中
load data local infile '/root/sql1.log' into table tb_user fields
terminated by ',' lines terminated by '\n' ;
(主键顺序插入性能高于乱序插入)
写个脚本造一下数据就好了,本例中的一亿数据最后是14个G的大小,mysql load时会逐渐占用硬盘,docker默认的10G硬盘扛不住一次都加载进去,所以进行了切分,最后分四次注入.每次注入25000000,在18分钟左右.