在测试过程当中,有时候需要准备大批量的测试数据,其中一个方法是直接向数据库插入大批量数据。 如在性能测试的时候,需要向数据库插入百万量级的测试数据,如何实现这一目标?
一、使用存储过程循环插入数据
DELIMITER //
CREATE PROCEDURE generate_data()
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE total_rows INT DEFAULT 1000;
-- 项目编号project_no默认为WS10043190001
DECLARE project_no VARCHAR(20) DEFAULT 'WS10043190001';
DECLARE sex ENUM('MALE', 'FEMALE');
WHILE i <= total_rows DO
-- Generate random values
SET @apply_no := CONCAT('apply', i);
SET @due_bill_no := CONCAT('apply', i);
SET @id_no := CONCAT('idno', i);
SET @user_id := CONCAT('user', i);
SET @user_name := CONCAT('user', i, ' name');
SET @phone := CONCAT('123456789', i);
SET @bank_card_no := CONCAT('123456789', i);
SET @account_name := CONCAT('account', i, ' name');
SET @bank_code := CONCAT('bank', i);
-- Insert into user_base table
INSERT INTO acc_loan.user_base (id, apply_no, batch_date, car_no, created_date, due_bill_no, hash_key, id_no, id_type, last_modified_date, phone, project_no, remark, sex, user_id, user_name, version)
VALUES (i, @apply_no, CURDATE(), NULL, NOW(6), @due_bill_no, MD5(@id_no), @id_no, 'ID_CARD', NOW(6), @phone, project_no, NULL, sex, @user_id, @user_name, NULL);
SET i = i + 1;
END WHILE;
END //
DELIMITER ;
-- 执行存储过程
CALL generate_data();
插入1000条数据耗时
二、使用临时表批量插入数据
DELIMITER //
CREATE PROCEDURE generate_and_insert_data()
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE j INT DEFAULT 1;
DECLARE total_iterations INT DEFAULT 1000;
DECLARE temp_id INT; -- 将DECLARE语句移动到BEGIN之前
DECLARE temp_apply_no VARCHAR(50); -- 将DECLARE语句移动到BEGIN之前
WHILE i <= total_iterations DO
-- 创建临时表用于存储生成的id和apply_no
CREATE TEMPORARY TABLE temp_data (
temp_id INT,
temp_apply_no VARCHAR(50)
);
-- 生成100个不重复的id和apply_no
WHILE j <= 100 DO
-- 生成随机的id和apply_no
SET temp_id = FLOOR(RAND() * 1000000) + 1;
SET temp_apply_no = CONCAT('APPLY_', temp_id);
-- 检查生成的id和apply_no是否已存在
WHILE EXISTS (SELECT * FROM temp_data WHERE temp_id = temp_id OR temp_apply_no = temp_apply_no) DO
SET temp_id = FLOOR(RAND() * 1000000) + 1;
SET temp_apply_no = CONCAT('APPLY_', temp_id);
END WHILE;
-- 将生成的id和apply_no插入到临时表中
INSERT INTO temp_data (temp_id, temp_apply_no) VALUES (temp_id, temp_apply_no);
SET j = j + 1;
END WHILE;
-- 将临时表中的数据插入到user_base表中
INSERT INTO acc_loan.user_base (id, apply_no, project_no, phone, id_no, id_type, batch_date, car_no, created_date, due_bill_no, hash_key, last_modified_date, remark, sex, user_id, user_name, version)
SELECT temp_id, temp_apply_no, 'WS10043190001', '15625172814', '511423199309110012', 'IDENTITY', CURDATE(), CONCAT('CAR_', temp_id), NOW(), temp_apply_no, MD5(CONCAT('IDNO_', temp_id)), NOW(), CONCAT('REMARK_', temp_id), IF(RAND() > 0.5, 'MALE', 'FEMALE'), CONCAT('USER_', temp_id), CONCAT('USER_NAME_', temp_id), NULL
FROM temp_data;
-- 删除临时表
DROP TEMPORARY TABLE IF EXISTS temp_data;
SET i = i + 1;
SET j = 1;
END WHILE;
END //
DELIMITER ;
CALL generate_and_insert_data();
三、使用prepare语句动态批量插入数据
每次插入100条数据
DELIMITER //
CREATE PROCEDURE insert_generate_data()
BEGIN
-- 声明变量
DECLARE i INT DEFAULT 1;
DECLARE total_iterations INT DEFAULT 10;
DECLARE project_no VARCHAR(20) DEFAULT 'WS10043190001';
DECLARE phone VARCHAR(100) DEFAULT '15625172814';
DECLARE id_no VARCHAR(100) DEFAULT '511423199309110012';
DECLARE id_type VARCHAR(20) DEFAULT 'IDENTITY';
WHILE i <= total_iterations DO
-- 生成100条不同的数据并插入到user_base表中
SET @sql = '';
SET @sql = CONCAT('INSERT INTO user_base (id, apply_no, batch_date, car_no, created_date, due_bill_no, hash_key, id_no, id_type, last_modified_date, phone, project_no, remark, sex, user_id, user_name, version) VALUES ');
SET @values = '';
-- 构造100条数据的VALUES子句
SET @j = 1;
WHILE @j <= 100 DO
-- 生成唯一的apply_no和due_bill_no
SET @apply_no = CONCAT('APPLY_', i * 100 + @j);
SET @due_bill_no = CONCAT('APPLY_', i * 100 + @j);
-- 生成随机的性别
-- SET @sex = IF(RAND() > 0.5, 'MALE', 'FEMALE');
-- 构造一条数据的VALUES子句
SET @values = CONCAT(@values,
'(', -- 拼接后是 (
i * 100 + @j,',', -- 拼接后是 101,
'"',@apply_no,'"',',', -- 拼接后是 "APPLY_101",
'"2022-01-01",', -- 拼接后是 "2022-01-01",
'"ABC123",', -- 拼接后是 "ABC123",
'"2023-09-12 06:22:31",', -- 拼接后是 "2023-09-12 06:22:31",
'"',@due_bill_no,'"',',', -- 拼接后是 "APPLY_101",
'"HASH_123",', -- 拼接后是 "HASH_123",
'"511423199309110012",', -- 拼接后是 "511423199309110012",
'"IDENTITY",', -- 拼接后是 "IDENTITY",
'"2023-09-12 06:22:31",', -- 拼接后是 "2023-09-12 06:22:31",
'"15625172814",', -- 拼接后是 "15625172814",
'"WS10043190001",', -- 拼接后是 "WS10043190001",
'"备注信息",', -- 拼接后是 "备注信息",
'"MALE",', -- 拼接后是 "MALE",
'"USER_123",', -- 拼接后是 "USER_123",
'"John Doe",', -- 拼接后是 "John Doe",
1,')' -- 拼接后是 1)
);
IF @j < 100 THEN
-- 这里拼完之后是否会多一个逗号?
SET @values = CONCAT(@values, ',');
END IF;
SET @j = @j + 1;
END WHILE;
SET @sql = CONCAT(@sql, @values);
-- 执行动态SQL
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET i = i + 1;
END WHILE;
END //
DELIMITER ;
call insert_generate_data();
插入1000条数据耗时: 每次插入1000条数据
DELIMITER //
CREATE PROCEDURE insert_copy_data()
BEGIN
-- 声明变量
DECLARE i INT DEFAULT 1;
DECLARE total_iterations INT DEFAULT 1;
DECLARE project_no VARCHAR(20) DEFAULT 'WS10043190001';
DECLARE phone VARCHAR(100) DEFAULT '15625172814';
DECLARE id_no VARCHAR(100) DEFAULT '511423199309110012';
DECLARE id_type VARCHAR(20) DEFAULT 'IDENTITY';
WHILE i <= total_iterations DO
-- 生成100条不同的数据并插入到user_base表中
SET @sql = '';
SET @sql = CONCAT('INSERT INTO user_base (id, apply_no, batch_date, car_no, created_date, due_bill_no, hash_key, id_no, id_type, last_modified_date, phone, project_no, remark, sex, user_id, user_name, version) VALUES ');
SET @values = '';
-- 构造100条数据的VALUES子句
SET @j = 1;
WHILE @j <= 1000 DO
-- 生成唯一的apply_no和due_bill_no
SET @apply_no = CONCAT('APPLY_', i * 1000 + @j);
SET @due_bill_no = CONCAT('APPLY_', i * 1000 + @j);
-- 生成随机的性别
-- SET @sex = IF(RAND() > 0.5, 'MALE', 'FEMALE');
-- 构造一条数据的VALUES子句
SET @values = CONCAT(@values,
'(', -- 拼接后是 (
i * 1000 + @j,',', -- 拼接后是 101,
'"',@apply_no,'"',',', -- 拼接后是 "APPLY_101",
'"2022-01-01",', -- 拼接后是 "2022-01-01",
'"ABC123",', -- 拼接后是 "ABC123",
'"2023-09-12 06:22:31",', -- 拼接后是 "2023-09-12 06:22:31",
'"',@due_bill_no,'"',',', -- 拼接后是 "APPLY_101",
'"HASH_123",', -- 拼接后是 "HASH_123",
'"511423199309110012",', -- 拼接后是 "511423199309110012",
'"IDENTITY",', -- 拼接后是 "IDENTITY",
'"2023-09-12 06:22:31",', -- 拼接后是 "2023-09-12 06:22:31",
'"15625172814",', -- 拼接后是 "15625172814",
'"WS10043190001",', -- 拼接后是 "WS10043190001",
'"备注信息",', -- 拼接后是 "备注信息",
'"MALE",', -- 拼接后是 "MALE",
'"USER_123",', -- 拼接后是 "USER_123",
'"John Doe",', -- 拼接后是 "John Doe",
1,')' -- 拼接后是 1)
);
IF @j < 1000 THEN
-- 这里拼完之后是否会多一个逗号?
SET @values = CONCAT(@values, ',');
END IF;
SET @j = @j + 1;
END WHILE;
SET @sql = CONCAT(@sql, @values);
-- 执行动态SQL
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET i = i + 1;
END WHILE;
END //
DELIMITER ;
call insert_copy_data();
插入1000条数据耗时