인덱스
- 책의 제일 끝에 있는
찾아보기
와 같은 것 - 데이터베이스 테이블의 모든 데이터를 검색해서 원하는 결과를 가져오려면 시간이 오래 걸리므로 칼럼의 값과 해당 레코드가 저장된 주소를 키와 값의 쌍으로 인덱스를 만들어두는 것
- 추가적인 쓰기 작업과 저장공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조
- 인덱스도 내용이 많아지면 원하는 검색어를 찾아내기 힘들기 때문에 주어진 순서로 미리
정렬
해서 보관 - 인덱스를 사용하지 않으면 전체를 탐색하는 Full Scan을 수행하는데, 이는 전체를 비교하여 탐색하기 때문에 처리속도가 떨어짐
인덱스와 자료구조
- SortedList는 DBMS의 인덱스와 같은 자료구조, 저장되는 값을 항상 정렬된 상태로 유지
- 인덱스도 SortedList와 마찬가지로 저장되는 칼럼의 값을 이용해 항상 정렬된 상태 유지
- ArrayList는 데이터 파일과 같은 자료구조, 값이 저장되는 순서대로 그대로 유지
- 데이터 파일은 ArrayList와 같이 저장된 순서대로 별도의 정렬 없이 그대로 저장
인덱스의 동작
- DBMS는 인덱스를 항상 최신의 정렬된 상태로 유지해야 원하는 값을 빠르게 탐색할 수 있음, 그렇기 때문에 인덱스가 적용된 칼럼에 INSERT, UPDATE, DELETE가 수행된다면 각각 다음과 같은 연산을 추가적으로 해줘야 하며 그에 따른 오버헤드가 발생
- INSERT : 새로운 데이터에 대한 인덱스를 추가
- DELETE : 삭제하는 데이터의 인덱스를 사용하지 않는다는 작업을 진행
- UPDATE : 기존의 인덱스를 사용하지 않음 처리하고, 갱신된 데이터에 대해 인덱스를 추가
인덱스의 장단점
- SortedList의 장단점을 통해 인덱스의 장단점을 알 수 있음
- 장점
- 데이터가 이미 정렬되어 있어서 원하는 값을 빨리 찾아올 수 있음
- 전반적인 시스템의 부하를 줄일 수 있음
- 단점
- 데이터가 저장될 때마다 항상 값을 정렬해야 하므로 저장하는 과정이 복잡하고 느림
- 인덱스를 관리하기 위해 DB의 약 10%에 해당하는 저장공간이 필요
- 인덱스를 관리하기 위해 추가 작업이 필요
- 인덱스를 잘못 사용할 경우 오히려 성능이 저하되는 역효과 발생
결론적으로 DBMS에서 인덱스는 데이터의 저장(INSERT, UPDATE, DELETE) 성능을 희생하고 데이터의 읽기 속도를 높이는 기능
인덱스 사용 시 주의할 점
- 테이블의 인덱스를 하나 더 추가할지 말지는 데이터의 저장 속도를 어디까지 희생할 수 있는지, 읽기 속도를 얼마나 더 빠르게 만들어야 하는지 여부에 따라 결정됨
- INSERT, UPDATE, DELETE 작업이 자주 일어나는 컬럼에는 인덱스를 사용하지 않는 것이 좋음
- DELETE와 UPDATE 연산 때문 : UPDATE와 DELETE는 기존의 인덱스를 삭제하지 않고 ‘사용하지 않음’ 처리를 해주는데 만약 어떤 테이블에 UPDATE와 DELETE가 빈번하게 발생된다면 실제 데이터는 10만 건이지만 인덱스는 100만 건이 넘어가게 되어, SQL문 처리 시 비대해진 인덱스에 의해 오히려 성능이 떨어지게 됨
- WHERE 절에(혹은 JOIN) 자주 사용되는 컬럼
- 인덱스를 부여한다고 반드시 성능이 향상되는 것이 아니므로, 인덱스를 부여한 뒤에 성능 테스트를 반드시 해봐야 함
- SELECT 쿼리 문장의 WHERE 조건절에 사용되는 칼럼이라고 전부 인덱스로 생성하면 데이터 저장 성능이 떨어지고 인덱스의 크기가 비대해져서 오히려 역효과를 불러올 수 있음
- 인덱스는 사용하는 것만큼 관리해주는 것도 중요, 사용하지 않는 인덱스는 바로 제거해주어야 함
인덱스를 사용하면 좋은 경우
- 규모가 작지 않은 테이블
- INSERT, UPDATE, DELETE가 자주 발생하지 않는 칼럼
- JOIN이나 WHERE 또는 ORDER BY에 자주 사용되는 칼럼
- 데이터의 중복도가 낮은 칼럼
- 조건절에 자주 등장하는 칼럼
- 항상 = 으로 비교되는 칼럼
- 중복되는 데이터가 최소한인 컬럼 (분포도가 좋은) 칼럼
- ORDER BY 절에서 자주 사용되는 칼럼
- JOIN 조건으로 자주 사용되는 칼럼
인덱스의 종류
- 인덱스는 데이터를 관리하는 방식(알고리즘)과 중복 값의 허용 여부 등에 따라 여러 가지로 나눌 수 있음
- 역할별로 구분
- Primary key : 그 레코드를 대표하는 칼럼의 값으로 만들어진 인덱스, 테이블에서 해당 레코드를 식별할 수 있는 기준값이 되기 때문에 식별자라고도 부름, NULL을 허용하지 않으며 중복을 허용하지 않음
- Secondary key : 프라이머리 키를 제외한 나머지 모든 인덱스는 보조 인덱스
- 데이터 저장 방식(알고리즘)별로 구분
- B-Tree 인덱스 : 가장 일반적으로 사용되는 인덱스 알고리즘, 칼럼의 값을 변형하지 않고 원래의 값을 이용해 인덱싱하는 알고리즘
- Hash 인덱스 : 칼럼의 값으로 해시 값을 계산해서 인덱싱하는 알고리즘, 매우 빠른 검색 지원하지만 값을 변형해서 인덱싱하므로 전방(prefix) 일치와 같이 값의 일부만 검색하고자 할 때는 사용할 수 없음, 주로 메모리 기반의 데이터베이스에서 사용
- 데이터의 중복 허용 여부로 구분
- Unique Index : 중복 허용 x, 같은 값이 1개만 존재함
- Non-Unique Index : 중복 허용 o
클러스터 인덱스 VS 비클러스터 인덱스
- 클러스터 인덱스
- 테이블 당 한 개만 생성 가능
- 행 데이터를 인덱스로 지정한 열에 맞춰서 자동정렬
- 영어 사전처럼 책의 내용 자체가 순서대로 정렬이 되어 있어 인덱스 자체가 책의 내용과 같음
- 비클러스터 인덱스보다 검색속도는 더 빠르지만 데이터의 입력, 수정, 삭제는 더 느림
- 비클러스터 인덱스
- 테이블 당 여러 개 생성 가능
- 비클러스터형 인덱스는 그냥 찾아보기가 있는 일반 책과 같음
- 인덱스 자체의 리프 페이지는 데이터가 아니라 데이터가 위치하는 포인터이기 때문에 클러스터형보다 검색 속도는 더 느리지만 데이터의 입력, 수정, 삭제는 더 빠름
- 인덱스를 생성할 때 데이터 페이지는 그냥 둔 상태에서 별도의 인덱스 페이지를 따로 만들기 때문에 용량을 더 차지함
클러스터 인덱스는 데이터의 위치를 바로 알기 때문에 그 데이터로 바로 접근할 수 있고 넌클러스터 인덱스는 페이지를 한 번 거쳐서 데이터에 접근하는 방식
인덱스의 생성
- 테이블 생성 시 하나의 열에 Primary Key를 지정하면 자동으로 클러스터형 인덱스 생성
- Primary Key를 지정하는 열에 강제적으로 비클러스터형 인덱스 지정 가능