현재 프로젝트에선 저장된 데이터의 양이 적지만 후에 데이터가 많이 쌓일것을 대비하여
레시피를 검색하는 부분의 성능을 향상시키고자 데이터베이스에 인덱스를 적용해보았습니다.
데이터베이스에서 인덱스란 테이블에 대한 검색 속도를 높여주는 자료구조입니다.
특정한 하나 또는 여러개의 컬럼을 복사하고 정렬시켜 목차의 역할을 합니다.
인덱스는 데이터베이스의 성능 향상 수단의 가장 일반적인 방법입니다.
그 이유는 아래 3가지가 있습니다.
- SQL문을 변경하지 않아도 된다.
- 테이블의 데이터에 영향을 주지 않는다.
- 일정한 효과를 기대할 수 있다.
이러한 비용대비 성능이 높은 방법이라 인덱스를 사용합니다.
효과적으로 인덱스를 설정하기 위해 몇가지 기준을 따르는게 좋습니다.
- 크기가 큰 테이블만 만든다.
크기가 작은 테이블은 인덱스와 풀 스캔에 큰 차이가 없습니다.
따라서 작은 테이블은 고려대상으로 삼을 필요가 없습니다.
- 기본키 제약이나 유일성 제약이 부여된 열에는 불필요하다.
기본키 제약이 부여된 열과 유일성 제약이 붙어 있는 열에는 자동으로 인덱스가 설정되어 있습니다.
- Cardinality가 높은 열에 만든다.
'Cardinality'란 '값의 분산도'를 나타내는 단아로, 특정 열에 대해 많은 종류의 값을 가지고 있다면 Cardinality가 높고 반대로 값의 종류가 적으면 Cardinality가 낮다는 의미입니다.
Cardinality가 높다면 인덱스를 통해 불필요한 값의 대부분을 걸러낼수 있을 것 이며,
반대로 낮다면 인덱스 트리를 따라가는 조작이 증가할수록 오버헤드가 증가해 인덱스를 작성한 혜택을 받지 못합니다.
MySQL에서 인덱스를 만들면 Index-type에 BTREE라고 적혀있습니다.
일반적으로 B-tree라 표기한다고 합니다.
B-tree에 대해 설명을 해보자면

위와같은 구조를 하고있고, 이진 검색 트리와 유사하지만 한 노드당 자식노드가 2개 이상 가능한게 특징입니다.
B-tree의 장점 한 가지는 '어떤 값에 대해서도 같은 시간에 결과를 얻을 수 있다' 입니다.
또한 루트로부터 리프까지의 거리가 일정한 균형트리로 이루어져있어 값에 따른 성능 불균형이 작도록 고안되어 있습니다.
또한 두번째 장점은 데이터의양이 증가할수록 우수한 개선효과를 발휘합니다.

데이터의 양이 적을때는 풀 스캔과 비슷한 차이를 보이면 때때론 성능이 악화되기도 하지만
데이터의 양이 늘어날수록 완만한 '로그함수 곡선'을 그리며 어떤 데이터 양(N)을 분기로
인덱스 스캔쪽이 우수한 성능을 보이게 됩니다.
현재 저장된 데이터가 재료는 900개, 레시피는 70개로 테이블의 크기가 너무 작아
성능개선을 보기 힘들어 데이터를 3000개씩 더 넣고 재료이름으로 인덱스를 만들어 테스트를 해봤습니다.
테스트는 재료를 통해 레시피아이디를 검색하는 쿼리문을 각각 15번씩 실행하고 첫번째를 제외한
나머지 14개 쿼리문의 평균 실행속도를 계산하였습니다.








| 재료 이름 | 인덱스 적용 전 평균 값 | 인덱스 적용 후 평균 값 | 결과 |
|---|---|---|---|
| 양파 | 0.00078833 | 0.00066951 | 약 15퍼센트 감소 |
| 감자 | 0.00075062 | 0.00071020 | 약 5퍼센트 감소 |
| 오이 | 0.00079054 | 0.00063210 | 약 15퍼센트 감소 |
| 파프리카 | 0.00072054 | 0.00062407 | 약 13퍼센트 감소 |
테이블의 크기가 여전히 작아 값의 차이는 작지만 감소 퍼센트로 보면 유의미한 결과를 보이고 있습니다.