MySQL8.0 Error Code: 1071. Specified key was too long 해결법

2022. 7. 15. 17:17데이터베이스

반응형

빠른 조회를 위해 테이블 속성에 인덱스를 걸려고 하는 참이었다.

그런데, 다음과 같은 에러가 발생했다.

머리털 나고 처음 보는 에러ㅋㅋ

Error Code: 1071. Specified key was too long; max key length is 3072 bytes

 

 

다름 아닌 인덱스 키의 최대 크기 제한이 있다는 것을 발견했다.

이것과 관련해서 글도 썼었는데 -_-;;; 이래서 실습이 중요하다.. 궁금하시다면 

https://leezzangmin.tistory.com/30

 

[MySQL8.0] B-Tree 인덱스 사용에 영향을 미치는 요소

이 글은 'Real MySQL 8.0 개발자와 DBA를 위한 MySQL 실전 가이드'를 보고 학습한 내용을 정리한 글입니다. B-Tree 인덱스는 인덱스를 구성하는 1. 칼럼의 크기와 2. 레코드의 건수 3. 유니크한 인덱스 키

leezzangmin.tistory.com

요약해서 말하자면, 스토리지 엔진의 페이지 크기 설정마다 다르지만 <인덱스의 크기는 아무리 커도 최대 3072B 까지만 허용된다 > 는 점이다. 

 

 

그럼, 인덱스를 걸려고 했던 테이블의 선언문을 보자.

CREATE TABLE IF NOT EXISTS `spring_cafe`.`post` (
    `post_id` BIGINT NOT NULL AUTO_INCREMENT,
    `post_subject` VARCHAR(1000) NOT NULL,
    `post_content` TEXT NOT NULL,
    `recommend_count` INT NOT NULL DEFAULT 0,
    `reference_category_id` BIGINT NOT NULL,
    `user_id` BIGINT NOT NULL,
    `created_at` DATETIME NOT NULL,
    `updated_at` DATETIME NOT NULL,
    `hit_count` BIGINT NOT NULL,
    PRIMARY KEY (`post_id`),
    INDEX `fk_post_post_category1_idx` (`reference_category_id` ASC) VISIBLE,
    INDEX `fk_post_users1_idx` (`user_id` ASC) VISIBLE,
    CONSTRAINT `fk_post_post_category1`
    FOREIGN KEY (`reference_category_id`)
    REFERENCES `spring_cafe`.`post_category` (`post_category_id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
    CONSTRAINT `fk_post_users1`
    FOREIGN KEY (`user_id`)
    REFERENCES `spring_cafe`.`users` (`user_id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
    ENGINE = InnoDB;

나는 post_subject 속성(글 제목)에 인덱스를 걸려고 했다. VARCHAR(1000) 으로 선언되어 있다. 사용중인 UTF8MB4 에서는 한 글자당 4바이트를 잡아먹는다. 따라서 인덱스의 크기는 4000바이트로 최대값인 3072바이트보다 크다..

그래서 인덱스가 만들어질 수 없는 것이 당연한 것이었다.

 

 


 

 

그렇다면, 이런 속성에는 인덱스가 무조건 생성될 수 없는 걸까?

걱정할 필요는 없다. 개발 선배님들은 다 계획이 있었다. 나이스

1. 속성의 크기를 줄인다.

-> VARCHAR(700)쯤으로 변경하면 2800바이트니까 작동은 된다. 그런데 기술적 문제 때문에 비즈니스에 영향을 준다..? 좀 아닌 것 같다. 패스

 

2. utf8mb4는 글자당 4바이트고 utf8은 3바이트니까 인코딩을 바꾸자!

-> 4000byte에서 3000byte가 되므로 인덱스 생성은 된다. 그럼 기존 데이터들은? 역시 이것도 패스. 말이 안된다.

 

3. 데이터 일부에만 인덱스를 건다.

-> 정답

create index test1 on post(post_subject(100));

속성 일부에만 인덱스를 거는 것도 가능했다.  해결!

데이터가 많아서 인덱스 생성도 시간이 걸린다.

 

 

끝으로 인덱스의 크기는 무조건 작은 것이 무조건 성능에 좋다. 프로그램 운영에 영향이 가지 않는 선에서 적절히 조절해서 사용하자.

 

 

반응형