potato.log
로그인
potato.log
로그인
유니크 인덱스
공부하는 감자
·
2024년 3월 11일
팔로우
0
mysql
0
MySQL
목록 보기
17/74
유니크 인덱스
유니크 인덱스란
유니크는 테이블이나 인덱스에 같은 값이 2개 이상 저장될 수 없음을 의미한다.
사실 인덱스라기보다는 제약조건에 가깝다고 볼 수 있다.
유니크 인덱스에서 NULL도 저장될 수 있다.
NULL은 특정 값이 아니므로 2개 이상 저장될 수 있다.
MySQL에서는 인덱스 없이 유니크 제약만 설정할 방법이 없다.
MySQL에서 프라이머리 키는 기본적으로 NULL을 허용하지 않는 유니크 속성이 자동으로 부여된다.
InnoDB 테이블의 프라이머리 키는 클러스터링 키의 역할도 하므로 유니크 인덱스와는 근본적으로 다르다.
유니크 인덱스와 일반 세컨더리 인덱스의 비교
유니크 인덱스와 유니크하지 않은 일반 세컨더리 인덱스는 사실 인덱스의 구조상 아무런 차이점이 없다.
따라서 두 인덱스의 읽기와 쓰기를 성능 관점에서 살펴본다.
인덱스 읽기
유니크 인덱스와 일반 세컨더리 인덱스의 읽기 성능 상 차이는 미미하다.
1개의 레코드를 읽느냐 2개 이상의 레코드를 읽느냐의 차이만 있다.
읽어야 할 레코드 건수가 같다면 성능상의 차이는 미미하다.
많은 사람들이 유니크 인덱스가 빠르다고 생각하지만, 이는 사실이 아니다.
유니크하지 않은 세컨더리 인덱스는 중복된 값이 허용되므로 읽어야 할 레코드가 많아서 느리지만, 이는 인덱스 자체의 특성 때문에 느린 것이 아니다.
레코드 1건을 읽는 데 0.1초가 걸리고 레코드 2건을 읽는 데 0.2초가 걸렸을 때 후자를 느리게 처리됐다고 할 수 없는 것과 같은 이치다.
하나의 값을 검색하는 경우 유니크 인덱스와 일반 세컨더리 인덱스는 사용되는 실행 계획이 다르지만, 이는 인덱스의 성격이 유니크한지 아닌지에 따른 차이일 뿐 큰 차이는 없다.
인덱스 쓰기
새로운 레코드가 INSERT되거나 인덱스 칼럼의 값이 변경되는 경우에는 인덱스 쓰기 작업이 필요하다.
유니크 인덱스 키 값을 쓸 때는 중복된 값의 유무를 체크하는 과정이 필요하기 때문에, 유니크하지 않은 세컨더리 인덱스의 쓰기보다 느리다.
MySQL에서는 유니크 인덱스에서 중복값을 체크할 때 읽기 잠금을 사용하고, 쓰기를 할 때는 쓰기 잠금을 사용하는데 이 과정에서 데드락이 아주 빈번히 발생한다.
InnoDB 스토리지 엔진에서는 인덱스 키의 저장을 버퍼링하기 위해 체인지 버퍼(Change Buffer)가 새용된다.
인덱스의 저장이나 변경 작업이 상당히 빨리 처리된다.
유니크 인덱스는 반드시 중복 체크를 해야 하므로 작업 자체를 버퍼링하지 못한다.
유니크 인덱스는 일반 세컨더리 인덱스보다 변경 작업이 더 느리게 작동한다.
유니크 인덱스 사용 시 주의사항
유일성이 꼭 보장되어야 하는 칼럼에 대해서는 유니크 인덱스를 생성하되, 꼭 필요하지 않다면 유니크 인덱스보다는 유니크하지 않은 세컨더리 인덱스를 생성하는 방법을 고려하자.
MySQL의 유니크 인덱스는 일반 다른 인덱스와 같은 역할을 하므로, 하나의 테이블에서 같은 칼럼에 유니크 인덱스와 일반 인덱스를 각각 중복해서 생성할 필요는 없다.
유니크 인덱스도 일반 세컨더리 인덱스와 같은 역할을 동일하게 수행할 수 있으므로, 세컨더리 인덱스를 중복으로 만들어 줄 필요는 없다.
똑같은 칼럼에 대해 프라이머리 키와 유닉스 인덱스를 동일하게 생성하지 않는다.
불필요한 중복이다.
유니크 인덱스는 쿼리의 실행 계획이나 테이블의 파티션에 미치는 영향이 있다.
자세한 내용은 10장 ‘실행 계획’과 13장 ‘파티션’에서 다룬다.
Reference
참고 서적
📔
Real MySQL 8.0
공부하는 감자
책을 읽거나 강의를 들으며 공부한 내용을 정리합니다. 가끔 개발하는데 있었던 이슈도 올립니다.
팔로우
이전 포스트
클러스터링 인덱스
다음 포스트
외래키
0개의 댓글
댓글 작성