B-TREE index를 적용한 이유
작성한 Query Dsl을 기반으로한 동적쿼리는 db에 full scan이 발생하게 되고
db의 데이터 수가 늘어나면 늘어날수록 조회시간은 길어지게 된다.
100만건을 기준으로 약 0.5초에서 1초 가량 걸리는데 이렇게 느린 검색 기능을 이용할 사용자는 아무도 없기 때문에
마치 책처럼 색인을 추가할 수 있는 index 기능을 적용하기로 했다.
인덱스(index)란?
데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조이다.
인덱스는 찾고자 하는 데이터의 주소값을 가지는 Index라는 테이블을 생성하게 되고
이 테이블에서 탐색 범위를 절반씩 줄여나가면서 데이터를 찾기 때문에 검색 성능을 향상 시킬 수 있다.
이는 트리구조의 자료구조와 유사한 기법이다.
책으로 예를 들자면 책의 맨 앞 혹은 맨 뒤에 색인이 추가되어 있는걸 볼 수 있는데
데이베이스의 index가 이와 같은 역할을 한다.
아래 그림은 인덱스의 동작 방식을 설명하기에 가장 좋아보여서 구글에서 가져와보았다.
인덱스의 장점과 단점
- 장점
- 테이블을 조회하는 속도와 그에 따른 성능을 향상시킬 수 있다.
- 전반적인 시스템의 부하를 줄일 수 있다.
- 단점
- 인덱스를 관리하기 위해 DB의 약 10%에 해당하는 저장공간이 필요하다.
- 인덱스를 관리하기 위해 추가 작업이 필요하다.
- 인덱스를 잘못 사용할 경우 오히려 성능이 저하되는 역효과가 발생할 수 있다.
검색 성능 향상 ( 검색기준 : 약 106만건 )
인덱스를 적용할 경우 위와 같은 검색결과를 얻을 수 있다.
책으로 비교를 해보자면 index를 적용하지 않은 경우는 책의 목차가 없다고 볼 수 있다.
책의 목차가 없다면 독자는 특정 내용을 찾기 위해 첫페이지부터 끝까지 일일이 내용을 찾게 되고
혹시라도 책의 분량이 적거나 찾고자하는 내용이 전반부에 있었다면 찾는 시간이 짧을지 몰라도
책의 분량이 많아지거나 내용이 후반부에 있다면 그만큼 찾는 시간은 오래 걸린다.
이와 같은 성능 향상이 있을 수 있었던 이유는
index를 적용하여 책의 목차가 생겼다고 가정을 한다면
독자가 찾는 내용이 몇 페이지에 있는지 바로 알 수 있게되고 해당 페이지로 이동해 원하는 정보를 얻을 수 있다.
사진과 같이 User가 18번 id에 해당하는 Query를 날렸다면..
18번 미만 그리고 18번을 초과하는 id는 조회조차 하지 않는다.
그리고 18번에 해당하는 id만 조회를 한뒤 Query가 지목하는 pointer를 발견했다면 DB로 이동해 해당 데이터를 가져온다.
index 생성 조회 삭제 (링크참고)
https://huskdoll.tistory.com/605
[mysql] 인덱스 생성, 삭제, 확인
인덱스 생성, 삭제 하는 방법 입니다. (샘플 테이블) 위 테이블과 같은 구조에 인덱스를 생성하는 예제 입니다. 1. 인덱스 추가로 생성 CREATE INDEX ON ( 칼럼명1, 칼럼명2, ... ); (예제) 1CREATE INDEX idx_tes
huskdoll.tistory.com
단일 index 와 복합 index의 차이
복합index란 2개이상의 컬럼으로 구성된 인덱스로 단일인덱스를 능가하는 성능을 낼수 있으며 여러개의 인덱스를
대신할수도 있다.
index의 문제
하지만 index의 경우 query로 보자면 like%에 해당하는 결과만 색인할 수 있다.
즉 %like나 %like%와 같은 결과에 대해서는 index가 걸리지않고 full scan이 발생하는데
이유는 인덱스는 컬럼의 값과 주소를 정렬하여 저장하는 색인인데
맨 처음값이 무엇인지 모른다면 인덱스를 참조하는 것이 불가능하기 때문이다.
이럴경우 full scan으로 검색을 한다.
index를 많이 생성하면 좋다?
아니다. 인덱스를 생성하는 것은 꼭 필요한 것만 생성해야한다.
- table에 쓰기가 발생할 경우 index도 변경이 발생한다.
- 여기서 중간쯤에 인덱스가 추가되어 write가 발생한다면 다시 정렬됨에 따라서
- 성능상의 부하를 주게 된다.
- 클러스터형 인덱스 생성시에는 데이터 전체가 다시 정렬된다.
- 인덱스를 생성하는 만큼 추가적인 저장 공간을 차지한다.
- 전체 데이터의 10 ~ 15%이내의 데이터가 출력될때만 index가 효율적이고
- 그 이상이 된다면 full scan이 더 빠르게 되는 경우가 발생할 수 있다.
- 인덱스를 생성하면 생성할수록 추가적인 저장 공간을 많이 차지하게 되고
%like%로 full scan이 아닌 인덱싱 방식으로 검색을 하려면?
full text index 방식을 사용해야한다.
긴 문자의 텍스트 데이터를 빠르게 검색하기 위한 mysql의 부가적인 기능으로
문자의 길이를 조절하면 %like%를 full scan없이 인덱스를 통해 검색할 수 있다.
'legacy > Pin-Table 성능 개선 기록' 카테고리의 다른 글
검색 성능 개선 #9 Composite Index (복합인덱스) (0) | 2023.02.26 |
---|---|
검색 성능 개선 #8 Optimizer에 의한 full scan 발생 (0) | 2023.02.09 |
검색 성능 개선 #6 방향성에 대한 고민2 (0) | 2023.02.09 |
검색 성능 개선 #5 DynamicSQL 코드 개선 (0) | 2023.02.09 |
검색 성능 개선 #4 동적쿼리(DynamicSQL) 구현 (0) | 2023.02.09 |