인덱스란 추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위해 데이터와 데이터의 위치를 포함한 자료구조이다.
// 인덱스 생성
CREATE INDEX 인덱스명 ON 테이블명 (컬럼명);
ALTER TABLE 테이블명 ADD INDEX 인덱스명 (컬럼명);
// 인덱스 삭제 (수정 시에는 DROP 후 재생성)
ALTER TABLE 테이블명 DROP INDEX 인덱스명;
1) 한 컬럼이 갖고 있는 값의 중복 정도가 낮을 수록 좋다.
2) INSERT, UPDATE, DELETE가 자주 발생하지 않는 컬럼일 수록 좋다.
3) JOIN이나 WHERE 또는 ORDER BY에 자주 사용되는 컬럼일 수록 좋다.
4) 인덱스 키의 크기는 되도록 작게 설계되어야 성능에 유리하다.
5) 분포도가 좁은 범위, 기본키, 조인과 연결 고리가 되는 컬럼을 인덱스로 구성한다.
6) 단일 인덱스 여러 개 보다 다중 컬럼 인덱스를 구성하는 게 좋다.
7) 되도록 동등 비교를 사용하는 것이 좋다.
8) 인덱스를 많이 생성하면 INSERT/DELETE/UPDATE의 성능 저하 원인이 될 수 있다.
9) 인덱스 생성 시 가장 효율적인 자료형은 정수형 타입이다. 가변적인 크기와 정규화 할 수 없는 데이터는 인덱스 생성 시 비효율적으로 동작한다.
1) 해시 테이블
해시 테이블은 (Key, Value)로 데이터를 저장하는 자료구조 중 하나로 빠른 데이터 검색이 필요할 때 유용하지만(O(1)), 등호(=) 연산에만 특화되어 있다. 해시 함수는 값이 1이라도 달라지면 완전히 다른 해시 값을 생성하는데, 이러한 특성에 의해 부등호 연산(>, <)이 자주 사용되는 데이터베이스 검색을 위해서는 해시 테이블이 적합하지 않다. B+Tree가 주로 사용된다.
2) B+Tree
DB의 인덱스를 위해 자식 노드가 2개 이상인 B-Tree를 개선시킨 자료구조이다. 리프노드만 인덱스와 함께 데이터를 가지고 있고, 나머지 노드들은 데이터를 위한 인덱스만을 갖는다. 부등호를 이용한 순차 검색 연산이 자주 발생될 수 있어서 B-Tree의 리프노드들을 LinkedList로 연결하여 순차검색을 용이하게 하는 등 B-Tree를 인덱스에 맞게 최적화하였다.
select *from product
where match(product_description) against ("편한 최고의 등산복!!!")
두 개 이상의 필드를 조합하여 생성한 인덱스이다. MYSQL은 하나의 인덱스에 최대 15개 컬럼으로 구성할 수 있다. 단일 컬럼 인덱스보다 INSERT/DELETE/UPDATE가 비효율적이기 때문에 변경이 없는 컬럼 값을 선정하는 것이 중요하다.
SELECT *FROM User_Info
WHERE name = 'hong' and address = 'seoul'
name, address가 단일 인덱스로 각각 있는 경우에는 두 컬럼 중 빠른 쪽을 먼저 검색하고 그 다음에 다른 컬럼을 검색한다.
다중 컬럼 인덱스의 경우는 인덱스 저장 시 name, address를 같이 저장하기 때문에 원하는 값을 바로 찾을 수 있다.
SELECT *FROM User_Info
WHERE address = 'seoul'
이 쿼리에서는 name이 없으므로 다중 컬럼 인덱스의 경우는 인덱스의 효과를 보지 못한다. 다중 컬럼 인덱스는 제일 왼쪽 컬럼이 where 절에서 사용되어야 한다.
*참고 자료
https://mangkyu.tistory.com/96
https://yurimkoo.github.io/db/2020/03/14/db-index.html
https://code-factory.tistory.com/24