MySQL如何大批量插入数据
  qNufQyMQglJ5 2023年11月02日 35 0

在测试过程当中,有时候需要准备大批量的测试数据,其中一个方法是直接向数据库插入大批量数据。 如在性能测试的时候,需要向数据库插入百万量级的测试数据,如何实现这一目标?

一、使用存储过程循环插入数据

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条数据耗时 图片.png

图片.png

二、使用临时表批量插入数据

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条数据耗时: 图片.png 每次插入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条数据耗时 图片.png

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  xaeiTka4h8LY   2024年05月31日   39   0   0 MySQL数据库
  xaeiTka4h8LY   2024年05月17日   52   0   0 数据库JavaSQL
  xaeiTka4h8LY   2024年05月17日   49   0   0 数据库SQL
  xaeiTka4h8LY   2024年05月17日   38   0   0 MySQL数据库
  xaeiTka4h8LY   2024年05月31日   38   0   0 数据库mongodb
qNufQyMQglJ5