테이블마다 인덱싱을 잘 걸어주면 속도가 빠름~ 빠름~
쿼리 속도가 늦어지는 이유는 뭘까?
- 컬럼수가 많거나
- 조인을 많이 하거나(테이블이 추가될 때마다 컬럼수가 +가 아니라 X로 적용됨)
- view를 사용하거나(테이블의 집합. 이미 많다..)
- 회사에서는 사용자가 많고 오래될 수록 테이블에 데이터가 쌓일 수 밖에 없다. 게다가 테이블이 엄청 많고 필요한 정보가 다 다른 테이블에 있어 조인이 필요하다면? 데이터가 적을 때는 primary key만으로도 인덱싱이 가능해서 문제가 되지 않겠지만, 데이터가 많아지게 되면 primary key만으로 인덱싱이 안된다. 또한 조회하는 테이블의 where 조건에 인덱스 값도 없고 primary key 값조차 존재하지 않는 경우 full scan이 발생하게 되므로 조회 속도에 영향을 주게 된다!
- 인덱스/인덱싱은 테이블 검색 속도를 올려줄 수 있는 색인을 의미! (참고)
쿼리 속도 확인하기
- explain
- mysql 쿼리의 실행 계획을 조회할 수 있는 명령
- 조회, 수정, 삭제 등 실행하려는 쿼리 앞에 explain 을 추가한다
- 결과 분석하기(예시)
- id 1인 row를 보면 table이 <derived2>라고 되어있다. 이것은 id가 2이고 select_type이 DERIVED인 테이블을 합쳐서 사용한다는 의미이다.
type이 ALL 이라고 되어있지만 select_type이 PRIMARY 이므로 크게 신경 쓰지 않아도 된다 - id 2인 row들을 보면 select_type이 DERIVED로 되어있다. 여기서 해당 row의 key와 rows 수를 봐야 한다
possible_keys는 현재 table에 걸려있는 primary와 index들 중 사용 가능한 것들의 목록이고, 실제 사용된 것은 key 컬럼에 나타난다.
해당 key를 사용하여 조회된 row 수가 rows에서 나타나고 id가 2인 row들의 rows가 누적으로 도출된다. - select_type이 DEPENDENT SUBQUERY인 row는 쿼리에서 subquery에 해당하는 테이블의 조회에 대한 부분이다
- 최종적으로 어떤 쿼리에 대해 결과 값을 가져오기 전 참조하는 테이블 rows가 많을 수록 속도가 느려지기 때문에 id가 1인 값이 적을 수록 속도가 빠르다고 할 수 있다
- id 1인 row를 보면 table이 <derived2>라고 되어있다. 이것은 id가 2이고 select_type이 DERIVED인 테이블을 합쳐서 사용한다는 의미이다.
- 더 많은 컬럼들에 대한 설명 : https://cheese10yun.github.io/mysql-explian
그러면 어떻게 조회 속도를 개선해야 할까?
- 인덱싱을 잘 걸어서 검색 속도를 개선 한다
- 쿼리를 잘 수정해서 검색 속도를 개선 한다
- 우리 회사의 경우 마이그레이션 수행시마다 데이터가 십만건만 넘어가도 속도 이슈가 항상 생겼었다. 그럴때 마다 테이블의 쿼리와 인덱스를 확인하여 이렇게 저렇게 추가하여 속도를 개선했지만 결국 근본적인 원인은 쿼리인 경우가 많았다(로컬 개발환경에서는 구분이 되는 값인데 실제 운영 환경에서는 구분이 안되는 값이었다던가..) 우선 문제가 되는 슬로우 쿼리를 확인하여 인덱싱을 걸어보고, 그래도 해결이 되지 않는다면 where절이나 join 부분 등을 수정하여 해결하는 것이 정석이지 않을까 싶다(아.. JPA 쓰고싶다)
반응형