"가장 일반적이면서 중요한 인덱스 방법은 B-Tree다. 모든 애플리케이션을 만족시킬 수 있는 최적의 메모리 구조란 존재하지 않지만, 그래도 하나를 선택해야 한다면 B-Tree를 선택할 것이라는 뜻이다." -Christopher J. Date [데이터베이스 시스템 6판]
인덱스의 구조에 따른 분류
B-Tree가 검색 알고리즘으로서는 뛰어나게 성능이 좋은 편이 아니지만, 군형이 잘 잡혀있기 때문에 RDB에서 많이 사용된다.
대부분의 데이터베이스에서는 트리의 리프 노드에만 키값을 저장하는 B+Tree라는
B-Tree의 수정 버전을 채택한다.
비트맵 인덱스
해시 인덱스
인덱스의 성능을 결정하는 요인
인덱스 설계란, 테이블 정의와 SQL만 봐서 할 수 있는 작업이 아니다.
SQL의 검색 조건과 결합 조건을 바탕으로 데이터를 효율적으로 압축할 수 있는 조건을 찾아야한다. -> 구문과 검색 키 필드의 카디널리티를 알아야 한다.
SELECT order_id, receive_date
FROM Orders;
실행 계획을 보지 않아도 테이블 풀 스캔이다.
레코드를 압축하는 WHERE 구가 없으므로 인덱스로 작성할만한 필드도 존재하지 않는다.
SELECT order_id, receive_date
FROM Orders
WHERE process_flg = '5';
process_flg의 분포
선택률이 83%로 굉장히 높은 수치이다.
인덱스가 제대로 작동하려면 '레코드를 크게 압축할 수 있는 검색 조건'이 있어야 한다.
입력 매개변수에 따라 0.01% ~ 10%의 선택률 차이가 난다고 가정했을 경우
성능 향상을 기대하기 어렵다.
10%일 경우 테이블 풀 스캔을 하고, 0.01%일 경우에는 인덱스 스캔을 하면 좋겠지만, 옵티마이저는 그러지 못한다.
압축할 검색 조건이 있지만, 인덱스를 사용할 수 없는 타입일 경우
SELECT order_id
FROM Orders
WHERE shop_name LIKE '%대공원%';
선택률은 0.005%로 가정한다.
이 경우에 shop_name 필드에 인덱스를 작성하면 효율적인 검색이 가능할까?
LIKE 연산자를 사용하는 경우 인덱스는 전방 일치('대공원%')에만 적용할 수 있다.
색인 필드로 연산하는 경우 인덱스를 사용할 수 없다.
SELECT *
FROM SomeTable
WHERE col_1 * 1.1 > 100;
그렇지만, 검색 조건의 우변에 식을 사용할 때는 인덱스가 사용된다.
이렇게 쓰면 됨
WHERE col_1 > 100/1.1
간단하게 마트 또는 개요 테이블(Summary Table)이라고 한다.
-> 데이터 신선도가 중요한 경우라면 데이터 마트를 채택할 수 없다.
테이블의 크기를 작게 해 I/O 양을 줄이는 것이 목적이므로 원래의 테이블에서 크기를 딱히 줄일 수 없다면, 소용없다.
데이터 마트 수가 100개를 넘는 경우도 있다.
-> 어떤 처리에 사용되는지가 혼동되면서 더 이상 사용하지 않는데도 쓸데없는 동기화가 일어나는 '좀비 마트'가 생기거나, 관리가 불가능해 질 수 있다.
접근하려는 대상의 I/O 감소를 목적으로 한다는 점에서는 데이터 마트와 같다.
인덱스를 사용한 고속화 방법이지만, 기존 인덱스와는 사용 방법이 많이 다르다.
SELECT order_id, receive_date
FROM Orders;
풀 스캔을 할 때 검색 대상을 테이블이 아닌 인덱스로 바꿀 수 있다.
CREATE INDEX CoveringIndex ON Orders (order_id, receive_date);
order_id, receive_date는 SELECT 구문에 포함되어 있으므로, 일반적으로 인덱스의 필드 후보로 되지 않는다.
그러나, 2개의 필드를 커버하는 인덱스가 존재하면, 테이블이 아닌 인덱스만을 스캔 대상으로 하는 검색을 사용할 수 있다. -> INDEX ONLY SCAN
-> 이러한 인덱스를 커버링 인덱스(Covering Index) 라 한다.
장점
로우(레코드) 지향 저장소의 DBMS에 유사적으로 컬러 기반 저장소를 실현하는 것