목차
인덱스 란?
추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조로 마치 책의 목차처럼 테이블 칼럼을 색인화 하여 검색 속도를 향상시키는 기술이다.
인덱스 종류
- 클러스터형 인덱스
- 인덱스 생성시 데이터 전체가 다시 정렬된다.
- 인덱스 자체의 리프페이지가 곧 데이터 페이지이다. (인덱스 자체에 데이터 포함)
- 보조 인덱스보다 검색 속도는 빠르나 입력/수정/삭제 작업에서는 더 느리다.
- 성능이 좋으나 테이블에 단 하나만 생성할 수 있다.
- Primary key로 지정하거나 unique not null 지정시 클러스터형 인덱스가 생성된다. 우선순위는 Primary key가 더 우선시 된다.
- 보조 인덱스 (논 클러스터형 인덱스)
- 데이터 페이지와 별개로 별도의 페이지에 인덱스를 구성한다.
- 리프페이지에 데이터가 아니라 데이터가 위치하는 주소값을 가지고 있다.
- 보조 인덱스를 테이블 당 여러가지 생성할 수 있으나, 남용 경우 시스템 성능을 떨어뜨리는 결과를 초래한다.
- not null이 아닌 unique 경우 보조 인덱스가 생성된다.
- 둘 혼합 경우
- 보조 인덱스 리프 페이지에 데이터 주소값이 아닌 클러스터형 인덱스의 키 값을 가지게 된다.
- 보조 인덱스 조회 후 다시 클러스터형 인덱스 조회
- 왜 보조 인덱스에 주소값을 넣지 않을까? 주소값으로 리프페이지에 저장되어 있으면, 데이터에 삽입 삭제 등으로 페이지 분할 등 변화가 생길 때, 클러스터형 인덱스의 하나 변화로 클러스터형 데이터페이지가 일단 페이지 변화, 오프셋 등이 대폭 변경이 된다. 이에 따라 보조 인덱스의 주소값 까지 대폭 변경되는 상황이 벌어져 큰 부하가 일어난다. 그래서 둘 혼합 경우 보조 인덱스의 리프페이지는 클러스터형 인덱스의 키 값만을 가지게 된 것이다.
인덱스 적용 방법
✅ 클러스터형 인덱스
- 생성 1 : 테이블 생성시 PRIMARY KEY 적용
CREATE TABLE 테이블이름 (
열이름 타입 PRIMARY KEY, // 클러스터형 인덱스
열이름 타입,
열이름 타입 UNIQUE, // 보조 인덱스
열이름 타입 UNIQUE NOT NULL, // 클러스터형 인덱스
};
- 생성 2 : 이미 생성된 테이블에 PRIMARY KEY 지정
ALTER TABLE 테이블이름 ADD PRIMARY KEY (열이름);
- 삭제 :
ALTER TABLE 테이블이름 DROP PRIMARY KEY;
✅ 보조 인덱스
- 생성
기본생성
형식:
CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX 인덱스이름
[index_type]
ON 테이블이름 (key_part, ...)
[index_option]
[algorithm_option | lock_option] ...
key_part :
{컬럼이름 [(length)|(expr)} [ASC | DESC}
index_option :
KEY_BLOCK_SIZE [=] value
| index_type
| WITH PARSER parser_name
| COMMENT 'string'
| {VISIBLE | INVISIBLE}
index_type :
USING {BTREE | HASH}
algorithm_option :
ALGORITHM [=] {DEFAULT | INPLACE | COPY}
lock_option :
LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}
간단하게
CREATE INDEX 인덱스이름 ON 테이블이름 (열이름);
- 이미 생성된 테이블에 INDEX 생성
ALTER TABLE 테이블이름 ADD INDEX 인덱스이름 (열이름);
- UNIQUE 제약조건으로 보조 인덱스 생성
ALTER TABLE 테이블이름 ADD CONSTRAINT UK_인덱스이름 UNIQUE (열이름);
- 삭제
DROP INDEX 인덱스이름 ON 테이블이름;
인덱스 성능 비교
조건) 정렬 안된 동일한 데이터가진 테이블 3개를 가지고 비교 (110만건 기준)
아래 명령어를 통해 검색시 몇개의 페이지를 읽었는 지 검색 이전과 이후의 값 차이로 알수있다.
show global status like 'Innodb_pages_read';
- 아무 인덱스도 없을때
- 읽기전
- 쿼리와 실행 계획 (Full Table Scan으로 작동)
select * from test_product_none where id = 100000;
- 읽은후
읽은후 값 - 읽기전 값 = 읽어들인 페이지 수
클러스터형도 보조도 없을 경우 조회를 위해 10658개를 읽어들였다.
- 클러스터형 인덱스가 있을때
- 읽기전
- 쿼리와 실행 계획 (클러스터형 인덱스 작동)
select * from test_product_cluster where id = 100000;
- 읽은후
! 클러스터형은 겨우 2페이지 만에 데이터를 찾아냈다.
- 보조 인덱스가 있을때
- 읽기전
- 쿼리와 실행 계획 (클러스터형 인덱스 작동)
select * from test_product_secondary where id = 100000;
- 읽은후
! 보조 인덱스 경우도 5페이지 만에 데이터를 찾아냈다.
인덱스 없이 데이터가 무려 10658개의 페이지를 읽었던 것과 비교하면 인덱스가 얼마나 유용한지 알 수 있다.
인덱스 설정시 고려사항
- WHERE 절에서 사용되는 열에 인덱스를 만들어야 한다.
- WHERE 절에 사용되더라도 자주 사용해야 가치가 있다.
- 데이터 중복도가 높은 열은 인덱스를 만들어도 효과가 없다.
- 외래 키를 지정한 열엔 자동으로 외래키 인덱스가 생성된다.
- JOIN이 자주 사용되는 열에 인덱스를 생성해 주는 것이 좋다.
- INSERT / UPDATE / DELETE 가 얼마나 자주 일어나는지 고려해야한다. 이 작업이 자주 일어나는 테이블에 인덱스를 쓰면 오히려 성능이 나빠진다 (페이지 분할이 빈번하게 발생하기 때문)
- 클러스터형은 테이블당 하나만 생성할 수 있다.
- 클러스터형 인덱스가 없는게 더 좋은 경우도 있다.
(새로운 데이터가 들어올때마다 정렬이 계속 수행되어 페이지 분할이 일어날 수도 있기 때문) - 사용하지 않는 인덱스는 제거해야 한다.
- 클러스터형과 보조 인덱스 혼합시
클러스터형 키 값으로 결정될 열은 최대한 적은 자릿수의 열을 선택하는 것이 좋다. 이 열 값으로 보조 리프페이지에도 저장되기 때문이다.
복합인덱스 (Composite Index, 결합인덱스, 멀티인덱스) 란?
인덱스 컬럼이 2개 이상 걸려있는 경우로 데이터가 많고 조건에 컬럼의 개수가 많을 경우에 사용한다.
인덱스에서는 선행 칼럼에서 걸러진 범위에서 그다음 컬럼이 걸러지고 연속해서 걸러진 범위안에서 값을 검색하기 때문에 인덱스 순서가 매우 중요하다.
- 인덱스 첫번째 컬럼을 Where절로 사용하지 않는다면 인덱스가 사용되지 않기 때문에 일단 공통적으로 사용하는 필수 조건절 컬럼을 우선시 해야한다.
- 조건(WHERE) 절에서 Equal('=')이 아닌 다른 연산자(BETWEEN, LIKE, <, >)의 첫 번째 컬럼까지만 인덱스를 사용하고 그 이후 컬럼들은 인덱스를 사용하지 않는다. (=,=,between,=,= 순서로 where절 조건을 넣었다면 3번째의 between까지만 인덱스를 사용한다. = 연산자 컬럼을 다른 연산자보다 우선으로 한다. (=이 아닌 첫번째 연산자 까지만 인덱스를 타지 않고 필터링 한다.)
추가 자료들
- 인덱싱 알고리즘 종류
- B-tree 알고리즘
가장 일반적으로 사용, 오래전부터 도입되어 많이 안정화 된 알고리즘. 컬럼 값을 변환하지 않고 원래 값을 이용해 인덱싱. - Hash 인덱스 알고리즘
컬럼 값으로 Hash 값을 계산하여 인덱싱하는 알고리즘으로 매우 빠른 검색을 지원. 변환된 값을 이용하여 인덱싱 하므로 LIKE 검색과 같은 주로 메모리 기반의 DB에서 많이 사용.
동등비교에 최적화되어 있고 부분일치 값을 검색하고자 할때는 사용 불가 - Fractal-Tree 알고리즘
B-tree 알고리즘의 단점을 보완을 위해 등장, 원래 값을 이용해 인덱싱. 데이터의 저장과 삭제 시 처리비용을 감축, 조만간 B-tree 알고리즘을 대체할 수 있을거라 예상.
- B-tree 알고리즘
'Database > MySQL' 카테고리의 다른 글
MySQL] WHERE vs HAVING (0) | 2023.04.01 |
---|---|
MySQL 설치 (Window ver.) (0) | 2023.03.05 |