DB 공부하다가 남기는 기록. 쿼리를 빠르게 돌리기 위해서 인덱스, 쿼리 힌트 사용하기가 있는데 정확히 그게 뭐고 어떻게 사용하는지 정리
1. 인덱스란?
데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조이다.
테이블 안의 데이터가 많다면 풀스캔을 해서 조회하면 시간이 너무 많이 걸림.
2. 인덱스의 내부 구조
B-Tree (balanced tree)
트리 구조로 균형있게 높이를 유지하도록 밸런스 맞춰서 저장한다. 노드안의 키는 정렬되어있다.
일반적인 트리는, 트리가 편향되어있고 최악의 경우를 생각하면 O(n) 의 시간이 걸린다.
밸런스가 맞춰져있다면 O(logN) 의 시간이 보장된다.
동작 방법
- 루트 노드부터 탐색한다.
- 노드의 키를 순회하면서 찾으면 탐색 종료한다.
- 못 찾으면 어떤 이웃한 두 키 사이의 값인지 보고, 그렇다면 자식 노드로 내려간다.
- 마지막 노드까지 반복한다.
3. 인덱스의 종류
클러스터드 인덱스
인덱스 - 데이터가 묶음으로 존재하는 것으로, 값을 찾기는 빠르지만 새로운 인덱스를 삽입해야한다면 정렬되어있는 다른 인덱스를 다 옮겨줘야해서 시간이 많이 소요된다.
- PK 를 생각해보면 됨
- 순서대로 정렬해놓음. 한 테이블에 하나만 존재한다.
- 범위 검색에 좋다
- 테이블 그 자체가 인덱스여서 따로 인덱스 저장 공간 필요하지 않다.
유니크 키와 Pk 를 혼동하지 않아야한다. 유니크해야한다고 무조건 pk 걸면 성능상에 문제가 생길 수 있다.(회원테이블에 메일주소를 pk 주는 경우 등)
논클러스터드 인덱스
순서에 상관없이 인덱스만 저장한다. 추가 저장 공간이 따로 필요하며 insert 시 인덱스를 생성하는 작업은 필요하다. 인덱스에서 데이터의 위치를 확인하고 다시 한번 그 데이터 접근하는 방식이다.
- 통상적으로 거는 인덱스 생각하면 됨
- 인덱스 기준으로 정렬되어 별도의 공간에 저장되어있음.
- 테이블과 매핑되어있어 인덱스에서 찾아서 테이블 가서 가져오는 것. (테이블 블럭의 주소를 가지고 있는 것처럼)
- where 절, order by 절에 자주 들어가는 내용을 걸어두는게 좋다.
- 여러 컬럼을 조합해서 인덱스로 구성할 수도 있다. 이 때 조합의 순서가 중요하다.
- 한 테이블에 여러개 가능하다.
그러나 인덱스를 마구잡이로 생성하면 insert 나 update 에서 속도가 느려질 수 있다. 어느 자리에 insert 해야할지 확인하고 인덱스에도 insert 해줘야하니까 느려진다. 또 인덱스는 update, delete 해도 사용 안함 처리만 하고 그대로 가지고 있어서 쓸데없이 볼륨만 커지는 경우가 있다.