유니크 인덱스

공부하는 감자·2024년 3월 11일
0

MySQL

목록 보기
17/74
post-thumbnail

유니크 인덱스

유니크 인덱스란

  • 유니크는 테이블이나 인덱스에 같은 값이 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

profile
책을 읽거나 강의를 들으며 공부한 내용을 정리합니다. 가끔 개발하는데 있었던 이슈도 올립니다.

0개의 댓글