Index의 이해
인덱스(Index)란?
- 인덱스는 RDBMS에서 검색속도를 높이기 위해 사용하는 하나의 기술
- 말 그대로 책의 맨처음 혹은 맨뒤에 있는 ‘목차’에 주로 비유된다.
DBMS도 데이터베이스 테이블의 모든 데이터를 검색(풀스캔)해서 원하는 결과를 가져 오려면 시간이 오래 걸린다.
그래서 칼럼의 값과 해당 레코드가 저장된 주소를 키와 값의 쌍으로 인덱스를 만들어 두고 SELECT 쿼리 사용시 해당 TABLE을 검색하는것이 아니라 빠른 B-TREE로 정리해둔 인덱스 파일의 내용을 검색한다.
정렬 되어있는 INDEX 파일을 검색하여 찾고자하는 데이터의 주소를 찾아 해당 데이터의 테이블에서 주소로 접근해 검색속도를 빠르게 하는 원리다.
Index 의 성능과 고려해야할 사항
SELECT 쿼리의 성능을 월등히 향상시키는 INDEX 항상 좋은 것일까? 모든 컬럼에 INDEX 를 생성해두면 빨라지지 않을까?
- INSERT 의 경우 INDEX 에 대한 데이터도 Index 테이블에 추가해야 하므로, 그만큼 성능에 손실이 따른다.
- 또한 Index 테이블은 정렬되어 있으므로 만약 중간에 삽입되어야 한다면, 그 아래 row들을 모두 한 칸씩 밀어야 한다.
- DELETE 의 경우 INDEX 에 존재하는 값은 삭제하지 않고 사용 안한다는 표시로 남게 된다.
- 즉 row 의 수는 그대로인 것이다. 이 작업이 반복되면 어떻게 될까?
- 실제 데이터는 10 만건인데 데이터가 100 만건 있는 결과를 낳을 수도 있는 것이다.
- UPDATE 의 경우는 INSERT 의 경우, DELETE 의 경우의 문제점을 동시에 수반한다.
- 이전 데이터가 삭제되고 그 자리에 새 데이터가 들어오는 개념이기 때문이다.
- 즉 변경 전 데이터는 삭제되지 않고 insert 로 인한 split 도 발생하게 된다.
- 즉 insert, update, delete (Command)의 성능을 희생하고 대신 select (Query)의 성능을 향상시킨다.
그렇다면 Index 어떻게 정해야할까?
- where절에 자주 등장하는(조회시 자주 사용하는) 컬럼을 Index로 지정하는 것이 좋다.
- 고유한 값 위주로 설정하는 것이 좋다.
- 카디널리티가 가장 높은 값으로 잡는 것이 좋다.
Cardinality란 무엇인가?
- 전체 행에 대한 특정 컬럼의 중복 수치를 나타내는 지표이다.
- 중복도가 ‘낮으면’ 카디널리티가 ‘높다’고 표현하고, 중복도가 ‘높으면’ 카디널리티가 ‘낮다’고 표현한다.
예를들어, 주민등록번호 같은 경우는 중복되는 값이 없으므로 카디널리티가 높다고 할 수 있다.
이에 비해 나이는 ‘주민등록번호에 비해’ 중복되는 값이 많으므로, 나이는 ‘주민등록번호에 비해’ 카디널리티가 낮다고 할 수 있다.
즉 인덱스를 걸 때, 내가 원하는 데이터를 선택하는 과정에서 최대한 많은 데이터가 걸러져야 성능이 좋을것이므로 주민등록번호로 인덱스를 걸면 나이로 인덱스를 거는 것보다 많은 데이터들이 걸러질 것이다.
Comments