😅 필자가 개인적으로 공부하고 남기는 것이기 때문에 정보가 미흡할 수 있습니다. 잘못된 내용이나 추천해주실 방법이 있을경우 댓글 남겨주신다면 감사히 받겠습니다.
일반적으로 Private key
가 없는 테이블을 생성하지는 않겠지만, MySQL은 유연성을 위해 Private key
가 없는 테이블 생성을 허용하고 있다.
필자는 Private key
가 없다면 오히려 성능만 낮아지고 이점이 별로 없을꺼 같은데 왜 MySQL은 이를 허용했는지 의문이였다.🤔 (물론 유연성이라는 이점은 있지만 이것만 있지는 않겠지..! 라는 생각을 했다.)
때문에 Private key
가 없는 테이블에대해 찾아보던 중 테이블을 생성할 때 Private key
가 없더라도 클러스터드 인덱스를 내부적으로 생성한다는 사실을 알게되었다.
데이터베이스 테이블의 행을 키 값에 따라 정렬하는 인덱스이다.
클러스터드 인덱스는 인덱스의 순서와 동일하게 디스크의 물리적인 순서를 유지하기 때문에 빠른 탐색이 가능하다. 때문에 InnoDB에선 Private key
를 생성하면 자동적으로 Private key
로 클러스터드 인덱스가 생성된다.
Private Key로 클러스터드 인덱스가 생성되어 pk가 존재해야만 클러스터드 인덱스가 생성되는 것으로 오해하고 있었다....
PK가 없는 테이블는 아래와 같이 두가지로 분리할 수 있다.
Unique 인덱스
가 존재하는 테이블Unique 인덱스
, Private key
모두 없는 테이블위와같이 분리한 이유는 클러스터드 인덱스를 생성하는 내부적인 동작방식의 차이가 있기 때문이다.
Uk가 존재하는 테이블은 테이블을 생성하는 시점에 Unique 인덱스
를 생성한다. 때문에 InnoDB는 테이블에 정의된 첫 번째 Unique인덱스
를 찾고, 이를 클러스터드 인덱스로 사용한다.
사실 최적화를 생각한다면 당연한 얘기이다. pk가 없으니 구분가능한 uk를 찾고 해당 인덱스를 기반으로 클러스터드 인덱스를 생성한다면 빨라지니 말이다.
하지만 2번처럼 Unique 인덱스
, Private key
모두 없는 테이블은 각 행을 구분할 수 있는 값이 존재하지 않는다. 그렇다면 클러스터드 인덱스를 어떻게 생성할까?
사실 InnoDB에는 테이블의 각 행마다 행 ID 값을 포함하는 가상의 컬럼이 존재한다. 이 행 ID 값은 6바이트로 구성되어있고 새로운 행이 삽입될 때마다 순차적으로 증가되도록 구현되어있다.
때문에 테이블에 Private key
나 적절한 Unique 인덱스
가 정의되어있지 않다면, 행 ID값을 사용해 "GEN_CLUST_INDEX"라는 클러스터드 인덱스를 생성한다.
MySQL docs를 살펴보면 아래와 같이 나와있다.
https://dev.mysql.com/doc/refman/8.0/en/innodb-index-types.html
필자는 클러스터드 인덱스를 무조건 생성해주는 이유가 무엇일지 고민해보았다.
먼저 PK,UK가 존재하는 경우 해당 컬럼을 통해 행에 접근할 수 있으니 속도 측면에서 이점이 발생한다.
하지만 PK가 없는 테이블은 조건 탐색이 없는 Where절을 사용하지 않는 테이블일텐데 어떤 이득이 있을까?
사실 이 고민은 클러스터드 인덱스의 장점을 생각하지 않은 고민이였다...ㅎ
클러스터드 인덱스는 데이터가 물리적으로 정렬되어있다.
때문에 전체탐색을 주로 진행하는 테이블의 경우 데이터에 순차적으로 액세스할 수 있으니 탐색속도가 빨라지게 된다.
https://stackoverflow.com/questions/18764/whats-the-difference-between-a-table-scan-and-a-clustered-index-scan
MySQL의 InnoDB엔진의 클러스터드 인덱스는 PK가 없더라도 모든 테이블에 생성된다~! 😅