diff --git a/_posts/2024-10-19-mysql-index.md b/_posts/2024-10-19-mysql-index.md index 8cab5e9..dd8b76e 100644 --- a/_posts/2024-10-19-mysql-index.md +++ b/_posts/2024-10-19-mysql-index.md @@ -21,7 +21,7 @@ date: 2024-10-19 23:59:59 +0900 toc: true --- -[K-DEVCON](https://k-devcon.com) 대전 오프라인 스터디에서 Real Mysql 책으로 스터디를 진행해보기로 했다. +[K-DEVCON](https://k-devcon.com) 대전 개발자 스터디에서 Real Mysql 책으로 스터디를 진행해보기로 했다. 발표하면서 준비한 내용을 블로그로도 옮겨보려고 한다. @@ -543,3 +543,67 @@ InnoDB 는 프라이머리 키가 없을 수 없다. ## where 절에서 조건문의 순서가 쿼리 성능에 영향을 미칠까? 옵티마이저가 index 구성과 통계정보에 따라 조건문의 순서를 적절히 조정한다. 따라서 일반적으로는 크게 영향을 미치지 않는다. 다만 복잡한 쿼리의 경우 달라질 수 있다. + +## 유니크키 + +유니크 인덱스와 일반 세컨더리 인덱스는 구조상 차이점이 없다. +유니크 키는 값은 값이 2개 이상 저장될 수 없도록 보장한다. + +프라이머리키와는 다르게 유니크는 NULL을 허용한다. + +### 유니크키의 읽기 성능 + +일반 인덱스와 거의 차이가 없다. +다만 1개만 반환하기 때문에 조금 더 빠르게 응답을 할 수 있지만 +이는 레코드 수의 차이라고 보면 된다. + +### 유니크키의 쓰기 성능 + +유니크 인덱스는 중복된 값이 있는지 없는지 체크하는 과정이 한 단계 더 필요하다. +또한 중복 체크는 바로 진행되어야 하므로 작업을 버퍼링 하지 못한다. +이 때문에 유니크 인덱스는 일반 세컨더리 인덱스보다 변경 작업이 더 느리게 작동한다. + +### 주의 사항 + +PRIMARY는 이미 UNIQUE 함을 보장한다. +UNIQUE 키를 추가할 수 있지만 이는 불필요한 중복이다. + +유니크 인덱스가 있다면 일반 인덱스를 만들어 줄 필요는 없다. +유니크 인덱스에서는 추가적으로 unique를 고장해줄 뿐이다. +추가적으로 인덱스를 생성할 필요는 없다. 불필요한 중복이다. + +## 외래키 (foreign key) + +외래키는 제약에 가깝다. 테이블 간의 관계를 정의하고, 데이터 무결성을 보장하는데 사용된다. 다른 인덱스들과 다르게 성능을 위한 인덱스는 아니다. + +### 외래키의 특징 + +테이블의 변경(쓰기 잠금)이 발생하는 경우에만 잠금 경합(잠금 대기)이 발생한다. 외래키와 연관되지 않은 칼럼의 변경은 최대한 잠금 경합(잠금 대기)을 발생시키지 않는다. + +### 외래 키 (foreign key) 의 동작방식 + +#### 자식 테이블의 변경이 대기하는 경우 + +부모 테이블의 해당 레코드가 쓰기 잠금이 걸려있으면 해당 쓰기 잠금이 해제될 때까지 기다린다. + +| 순서 | 커넥션 1 | 커넥션 2 | +| ---- | ----------------------------------------------- | --------------------------------------- | +| 1 | BEGIN; | | +| 2 | UPDATE tb_parent SET fd='changed-2' WHERE id=2; | | +| 3 | | BEGIN; | +| 4 | | UPDATE tb_child SET pid=2 WHERE id=100; | +| 5 | ROLLBACK; | | +| 6 | | Query OK, 1 row affected (3.04 sec) | + +#### 부모 테이블의 변경 작업이 대기하는 경우 + +자식 테이블의 레코드가 쓰기 잠금이 걸려있으면 해당 쓰기 잠금이 해제될 때까지 기다린다. + +| 순서 | 커넥션 1 | 커넥션 2 | +| ---- | -------------------------------------------------- | ----------------------------------- | +| 1 | BEGIN; | | +| 2 | UPDATE to_child SET fd='changed-100' WHERE id=100; | | +| 3 | | BEGIN; | +| 4 | | DELETE FROM to_parent WHERE id=1; | +| 5 | ROLLBACK; | | +| 6 | | Query OK, 1 row affected (6.09 sec) |