저번 시간에 이어서, 이번엔 Index에 대한 다양한 질문들을 알아보겠습니다. Index는 굉장히 자주 등장하는 면접 질문입니다. 다방면으로 준비하시길 권해드립니다. 서비스 플랫폼 기업 N, K, L, T사에서 마주한 경험이 있습니다.
Q: Index는 왜 필요한가요?
TABLE의 검색 성능을 높여주기 위해 필요합니다. 일반적인 RDBMS에서는 B+Tree구조로 된 index를 사용하여 검색 속도를 향상시킵니다.
- index는 Btree, B+tree, Hash, Bitmap으로 구현될 수 있습니다.
index는 책마다 마지막 페이지에 있는 색인과 같은 역할을 하는 자료구조입니다. 책에서 어떤 용어나 단어를 찾기 위해 첫 페이지부터 끝 페이지 까지 전체를 훑지 않아도(Full Table Scan) index를 찾아보면 몇 페이지에 적혀 있는지 바로 찾을 수 있는 것(Index Scan)과 비슷합니다.
SELECT ~ WHERE Query를 통해 특정 조건을 만족하는 데이터를 찾을 때, Full Table Scan할 필요 없이 정렬되어 있는 index에서 훨씬 빠른 속도로 검색을 할 수 있게 됩니다.
Q: 클러스터드 인덱스와 넌클러스터드 인덱스의 차이를 말해보세요.
클러스터드 인덱스는 PK 기준, 자동 오름차순 정렬이고 상대적으로 크기가 작습니다. 선택도 30% 이하일 때 사용하기 좋고, 한 테이블에 1개만 존재할 수 있습니다.
넌클러스터드 인덱스는 자동으로 정렬하지 않고, 상대적으로 크기가 큽니다. 선택도는 3% 이하일 때 사용하기 좋고 한 테이블에 최대 249개 존재할 수 있습니다.
Q: 커버링 인덱스가 무엇인가요?
쿼리를 충족시키는 데 필요한 모든 데이터를 갖고 있는 인덱스를 의미합니다. 인덱스만 읽고 처리하는 쿼리를 Covered Query라고 부릅니다.
Q: 클러스터형 인덱스와 보조 인덱스를 설명해 보세요
- Clustering index: 특정 Column을 기본키로 지정하면 자동으로 클러스터형 인덱스가 생성되고, 해당 column 기준으로 정렬이 됩니다. Table 자체가 정렬된 하나의 index라할 수 있습니다.
- Secondary index: 일반 책의 찾아보기와 같이 별도의 공간에 index가 생성됩니다. create index와 같이 index를 생성하거나 고유키(unique key)로 지정하면 보조 인덱스가 생성됩니다.
Q: index의 단점은 무엇인가요?
크게 2 가지가 있습니다.
- 첫째로, 추가 저장공간이 필요합니다. 보통 Table의 10%정도를 차지합니다.
- 둘째로, 느린 데이터 변경 작업입니다. B+tree 구조의 index는 데이터가 추가/삭제 될 때마다 tree의 구조가 변경될 수 있으며, index의 재구성이 필요하기 때문에 추가적인 자원이 소모됩니다.
Q: index를 많이 생성하면 안 되나요?
index를 생성하면 조건 검색 성능이 향상될 수 있지만, 추가 저장 공간이 필요하고, 데이터 추가/수정/삭제를 할 때마다 관련 index를 모두 수정해줘야 되기 때문에 시간이 추가적으로 소요됩니다. 따라서 추가 저장 공간과, 데이터 업데이트 시 소요되는 추가 시간 등의 Trade off를 고려하여, 조건 검색 성능 향상이 더 큰 이득이 된다고 판단되는 Column에만 index를 생성하는 것이 좋습니다.
Q: index를 어느 Column에 사용하는 것이 좋을까요?
where 절에서 자주 사용되고, 수정 빈도가 낮으며, 카디널리티는 높고, 선택도가 낮은 column을 선택하는 것이 좋습니다.
- 카디널리티 : 높을수록 적합(데이터 중복이 낮을수록 적합)
- 선택도 : 낮을수록 적합
- 조회 활용도 : 높을수록 적합(where 절에서 많이 사용되면 적합)
- 수정 빈도 : 낮을수록 적합
Q: 고객 DB에서 성별 column에 index를 걸어주는 게 좋을까요? Where절에서 자주 사용될 수 있잖아요?
성별은 남녀 두 종류로만 나눠지는 경우에는 카디널리티가 매우 낮고, 선택도는 매우 높게 됩니다. 이 경우, index가 주는 이점이 매우 적고 오히려 저장공간 차지와 데이터 수정 시 성능 저하등을 고려하여 index를 생성하지 않는 것이 좋습니다.
Q: true 또는 false 값을 갖는 column에서, true 1%, false 99%의 비율로 구성된 상황에서는 index를 거는 게 좋을까요?
역시 두 종류로 나누어 지기 때문에, 카디널리티가 매우 낮고, 선택도는 매우 높게 됩니다. 이 경우 index가 주는 이점이 매우 적고 오히려 저장 공간 차지와 데이터 수정 시 성능 저하등을 고려하여 index를 생성하지 않는 것이 좋습니다.
Q: 데이터를 검색할 때 hash table의 시간복잡도는 O(1)이고 b+tree는 O(logn)으로 더 느린데 왜 index는 hash table이 아니라, b+tree로 구현되나요?
Hash table을 사용하면 하나의 데이터를 탐색하는 시간은 O(1)로 b+tree보다 빠르지만, 값이 정렬되어 있지 않기 때문에 부등호를 사용하는 query에 대해서는 매우 비효율적이게 되어 데이터를 정렬해서 저장하는 b+tree를 이용합니다.
Q: Hash index는 언제 효율적일까요?
빠른 데이터 검색이 필요할 때 유용합니다. 하지만, index로써 hash index가 사용되는 경우는 제한적입니다. 왜냐하면 hash index는 등호(=) 연산에만 특화되었기 때문입니다. 데이터가 조금이라도 달라지면, hash function은 완전히 다른 hash 값을 생성하는데, 이러한 특성 때문에 부등호 연산(>, <)이 자주 사용되는 DB 검색에는 hash index가 적합하지 않습니다.
Q: MySQL 인덱스는 어떤 자료구조를 사용하나요?
B+Tree 자료구조를 사용합니다.
Q: B-Tree를 사용하지 않는 이유는 무엇인가요?
B-Tree는 특정 데이터의 검색엔 효율적이지만, 모든 데이터를 순회하는 경우엔 모든 노드를 방문해야 하므로 비효율적입니다.
따라서 MySQL에서는 B+Tree를 사용하여 모든 데이터는 리프노드에 저장 되고, Double Linked List로 연결되어 있기 때문에 순회에 매우 유리합니다.
마치며
이번 시간에는 Index에 대한 다양한 질문들을 알아보았습니다. 실제로 출제 빈도가 높으며, 현업에서도 항상 사용되기 때문에 깊게 숙지시키고 넘어가시길 권해드리고 싶습니다.
다음 시간에는, Replication에 대해 알아보겠습니다.
답글 남기기