Index 없는 테이블 생성
DDL
DROP TABLE IF EXISTS member;
CREATE TABLE member
(
id bigint NOT NULL AUTO_INCREMENT,
nickname varchar(8) NOT NULL,
created_at datetime(6) NOT NULL,
PRIMARY KEY (id)
) ENGINE = InnoDB;
DROP TABLE IF EXISTS crew;
CREATE TABLE crew
(
id bigint NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
created_at datetime(6) NOT NULL,
updated_at datetime(6) NOT NULL,
PRIMARY KEY (id)
) ENGINE = InnoDB;
DROP TABLE IF EXISTS crew_participant;
CREATE TABLE crew_participant
(
id bigint NOT NULL AUTO_INCREMENT,
crew_id bigint NOT NULL,
member_id bigint NOT NULL,
request_at datetime(6) NOT NULL,
PRIMARY KEY (id)
) ENGINE = InnoDB;
Dummy 데이터 삽입
Procedure 생성
DELIMITER $$
DROP PROCEDURE IF EXISTS member_loop $$
CREATE PROCEDURE member_loop()
BEGIN
DECLARE idx INT DEFAULT 1;
WHILE idx <= 2000
DO
INSERT INTO member(nickname, created_at)
VALUES
(CONCAT('n_', idx), NOW());
SET idx = idx + 1;
END WHILE;
END $$
DELIMITER ;
DELIMITER $$
DROP PROCEDURE IF EXISTS crew_loop $$
CREATE PROCEDURE crew_loop()
BEGIN
DECLARE idx INT DEFAULT 1;
WHILE idx <= 2000
DO
INSERT INTO crew(name, created_at, updated_at)
VALUES
(CONCAT('n_', idx), NOW(), NOW());
SET idx = idx + 1;
END WHILE;
END $$
DELIMITER ;
DELIMITER $$
DROP PROCEDURE IF EXISTS crew_participant_loop $$
CREATE PROCEDURE crew_participant_loop()
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE j INT DEFAULT 1;
SET @member_count = ( SELECT COUNT(id) FROM member );
SET @crew_count = ( SELECT COUNT(id) FROM crew );
WHILE i <= @member_count
DO
SET j = 1;
WHILE j <= @crew_count
DO
INSERT INTO crew_participant(crew_id, member_id, request_at) VALUES (i, j, NOW());
SET j = j + 1;
END WHILE;
SET i = i + 1;
END WHILE;
END $$
DELIMITER ;
Procedure 실행
CALL member_loop;
CALL crew_loop;
CALL crew_participant_loop;
테이블 확인
SELECT COUNT(id) FROM member
UNION ALL SELECT COUNT(id) FROM crew
UNION ALL SELECT COUNT(id) FROM crew_participant;
Index 있는 테이블 생성
테이블 복사
crew_participant
테이블 구조를 복사하여 새로운 new_crew_participant
테이블을 만들어 주고 crew_participant 테이블 내용을 new_crew_participant 테이블에 복사해준다. 그리고 UNIQUE INDEX
가 있는 테이블을 만들어줄 것이기 때문에 crew_id, member_id
을 묶어 Unique Multi Column 인덱스 제약조건을 걸어준다.
CREATE TABLE 새로운_테이블명 LIKE 복사할_테이블명; 쿼리는 테이블 구조를 복사할 때 제약조건까지 모두 복사한다.
CREATE TABLE new_crew_participant LIKE crew_participant;
INSERT INTO
new_crew_participant
SELECT
*
FROM
crew_participant;
ALTER TABLE new_crew_participant
ADD UNIQUE INDEX crew_member_index (crew_id, member_id);
데이터 및 제약조건 확인
SELECT COUNT(id) FROM new_crew_participant;
SHOW CREATE TABLE new_crew_participant;
SHOW INDEX FROM new_crew_participant;
테스트
Index 여부 확인
SHOW INDEX FROM crew_participant;
SHOW INDEX FROM new_crew_participant;
프로파일링
SHOW VARIABLES LIKE '%profiling_history_size%';
SET profiling_history_size = 2;
SET PROFILING = 1;
SELECT * FROM crew_participant WHERE crew_id = 1700 AND member_id = 300;
SELECT * from new_crew_participant WHERE crew_id = 1700 AND member_id = 300;
SET PROFILING = 0;
SHOW PROFILES;
사용하는 Index 확인
EXPLAIN SELECT * FROM crew_participant WHERE crew_id = 1700 AND member_id = 300;
EXPLAIN SELECT * FROM new_crew_participant WHERE crew_id = 1700 AND member_id = 300;