쿼리튜닝과 인덱스

 약 한달 전 조회 조건을 추가해달라는 요청이 왔고 대수롭지 않게 추가했던 적이 있다.

LEFT JOIN tb_review re ON re.care_no = ca.care_no AND re.delete_yn = 'N' AND re.reg_type = '0'

이게 전체 조회량을 늘리고 늘려서 화면을 다운시킨다는 것을 알게 되었는데, 일반적으로는 join에 and조건을 걸으면 이런 현상이 일어난다고 한다. 그래서 사수님은 이걸 1차적으로 분리해서 작성했고, 시간이 12초에서 1초 내로 줄어드는 효과를 보았다. 

LEFT JOIN tb_review re ON re.care_no = ca.care_no 
WHERE 1=1 
AND re.delete_yn = 'N' AND re.reg_type = '0'

아니 근데 이건 다시 확인하니까 조회 대상이 바뀌는 변화인 것. 전과 같은 결과를 위해 다시 쿼리를 돌려야 했고 EXPLAIN 명령어로 해당 쿼리를 조사해보자 review 테이블에서 care_no를 인덱싱 없이 ALL로 조회하고 있음이 나왔다. 여기에 인덱스를 추가해줘서 결국 같은 결과를 1/10 이하의 시간으로 조회가 가능케 했는데 이에 너무 신기해서 인덱스에 대해 살짝 정리해볼까 한다. 

show index from tb_review;

명령어로 해당 테이블에 걸려 있는 인덱스를 확인할 수 있다. 

가장 위에 있는 것은 해당 테이블의 PK로 이건 mysql에서 자동적으로 걸어 주니 중복해서 걸지 않도록 주의해야 한다. 아래의 2개가 사용자가 직접 걸어준 인덱스다.

non_unique

1이면 중복 허용, 0이면 유니크 값이다.

key_name

인덱스의 이름으로 기본키는 항상 PRIMARY

seq_in_index

인덱스의 열 시퀀스 번호, 시작은 1부터 시작한다.

collation

정렬 방식, A는 오름차순, B는 내림차순, NULL은 정렬되지 않음을 의미

cardinality

인덱스에서 예상되는 고유 값 수, 해당 값이 높을 수록 조회에 인덱스를 사용할 가능성이 높아지고 효율도 증가한다. 즉 겹치는 값이 별로 없다 -> 카디널리티가 높다 -> 인덱스 효율 증가 

sub_part

인덱싱 접두사, 전체 열이 인덱싱 된 경우 null. 부분적으로 인덱싱 된 경우 인덱싱 된 문자 수를 표시한다.

packed

키가 패킹되는 방법을 나타내고, 패킹되지 않는 다면 null.

null

NULL값을 포함할 수 있다면 YES, 그렇지 않다면 공백.

index_type

사용되는 인덱스 메서드, 종류는 BTREE, HASH, RTREE 또는 FULLTEXT

comment

열에서 설명 되지 않는 인덱스 정보.

index_comment

comment를 사용 하여 인덱스를 작성할 때 지정 색인에 대한 설명 

각 컬럼은 위의 설명을 가진다. 

EXPLAIN  

mysql이 쿼리를 어떻게 판단해서 실행하는 지에 대한 정보를 볼 수 있다. SELECT 앞에 해당 명령어를 추가하는 것으로 사용.

보통 타입을 확인한다. 



EXPLAIN 보는 방법

type를 확인

const

PRIMARY KEY 또는 UNIQUE 인덱스의 룩업에 따라 접근.최고속도.

eq_ref

JOIN 따른 PRIARY KEY 또는 UNIQUE KEY 가 이용되는 시점의 접근 타입. const와 비슷하지만 JOIN에서 사용되는 것이 다름.

ref

유니크(PRIMARY or UNIQUE) 가 없는 인덱스를 사용해서 등가 검색을(WHERE key = value) 실행할때 사용되는 접근 타임.

range

인덱스를 사용한 범위 검색

index

풀 인덱스 스캔.인덱스 전체를 스캔할 필요가 있기 때문에 매우 느림.

ALL

풀 테이블 스캔. 인덱스가 전혀 사용되지 않은 것을 의미.OLPT계의 처리에서는 개선이 필요.

댓글

이 블로그의 인기 게시물

git-receive-pack not permitted on 깃 허브 로그인 관련 문제