-- User 테이블 생성CREATETABLE IF NOTEXISTS `User` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`nickname` VARCHAR(30) NOTNULL,
`rank` INTNOTNULLCHECK (`rank` BETWEEN1AND10),
`money` BIGINTNOTNULLCHECK (`money` BETWEEN1AND99999999),
`start_date` DATENOTNULL,
`last_login` DATETIME
);
-- 인덱스 생성CREATE INDEX idx_user_rank ON `User`(`rank`);
CREATE INDEX idx_user_money ON `User`(`money`);
CREATE INDEX idx_user_start_date ON `User`(`start_date`);
CREATE INDEX idx_user_nickname ON `User`(`nickname`);
DELIMITER //CREATEFUNCTION random_korean_name() RETURNSVARCHAR(30)
NOTDETERMINISTICNOSQLBEGINDECLARE surnames VARCHAR(100) DEFAULT'김,이,박,최,정,강,조,윤,장,임';
DECLARE names VARCHAR(200) DEFAULT'준,민,서,예,지,현,우,아,은,진,선,영,주,혜,성,민,정,수,윤,태';
DECLARE surname VARCHAR(10);
DECLARE name1 VARCHAR(10);
DECLARE name2 VARCHAR(10);
SET surname = SUBSTRING_INDEX(SUBSTRING_INDEX(surnames, ',', FLOOR(1+ RAND() *10)), ',', -1);
SET name1 = SUBSTRING_INDEX(SUBSTRING_INDEX(names, ',', FLOOR(1+ RAND() *20)), ',', -1);
SET name2 = SUBSTRING_INDEX(SUBSTRING_INDEX(names, ',', FLOOR(1+ RAND() *20)), ',', -1);
RETURN CONCAT(surname, name1, name2);
END//
DELIMITER ;
-- 랜덤 데이터 생성 및 삽입을 위한 프로시저
DELIMITER //CREATEPROCEDURE generate_user_data(IN num_records INT)
BEGINDECLARE i INTDEFAULT0;
WHILE i < num_records DO
INSERTINTO `User` (nickname, `rank`, money, start_date, last_login)
VALUES (
random_korean_name(),
FLOOR(1+ RAND() *10),
FLOOR(1+ RAND() *99999999),
DATE_SUB(CURDATE(), INTERVALFLOOR(RAND() *365*3) DAY),
IF(RAND() <0.8,
DATE_SUB(NOW(), INTERVALFLOOR(RAND() *180) DAY),
NULL)
);
SET i = i +1;
END WHILE;
END//
DELIMITER ;
-- 데이터 생성 실행CALL generate_user_data(3000);
-- 통계 업데이트
ANALYZE TABLE `User`;
6000초로 임시 설정.
개선
-- 1. 임시 테이블 생성CREATETABLE IF NOTEXISTS `User_Temp` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`nickname` VARCHAR(30) NOTNULL,
`rank` INTNOTNULL,
`money` BIGINTNOTNULL,
`start_date` DATENOTNULL,
`last_login` DATETIME
) ENGINE=InnoDB;
-- 2. 랜덤 데이터 생성 및 삽입을 위한 프로시저
DELIMITER //CREATEPROCEDURE generate_user_data_optimized(IN num_records INT, IN batch_size INT)
BEGINDECLARE i INTDEFAULT0;
-- 트랜잭션 시작START TRANSACTION;
WHILE i < num_records DO
INSERTINTO `User_Temp` (nickname, `rank`, money, start_date, last_login)
SELECT
random_korean_name(),
FLOOR(1+ RAND() *10),
FLOOR(1+ RAND() *99999999),
DATE_SUB(CURDATE(), INTERVALFLOOR(RAND() *365*3) DAY),
IF(RAND() <0.8,
DATE_SUB(NOW(), INTERVALFLOOR(RAND() *180) DAY),
NULL)
FROM (SELECT@rn:=@rn+1AS rn FROM (SELECT@rn:=0) AS r,
information_schema.columns LIMIT batch_size) AS t
WHERE t.rn <= batch_size;
SET i = i + batch_size;
-- 일정 간격으로 커밋
IF i % (batch_sizeid *10) =0THENCOMMIT;
START TRANSACTION;
END IF;
END WHILE;
-- 남은 데이터 커밋COMMIT;
END//
DELIMITER ;
-- 3. 데이터 생성 실행 (배치 크기: 10000)CALL generate_user_data_optimized(3000000, 5000);
-- 4. 임시 테이블에서 실제 테이블로 데이터 이동INSERTINTO `User` SELECT*FROM `User_Temp`;
-- 5. 임시 테이블 삭제DROPTABLE `User_Temp`;
-- 6. 통계 업데이트
ANALYZE TABLE `User`;