Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
drunkenhw committed Sep 3, 2023
1 parent 62b87e5 commit ed1a3a3
Showing 1 changed file with 15 additions and 15 deletions.
30 changes: 15 additions & 15 deletions _posts/2023-09-03-improved-query-performance.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: '실행 계획에서 using temporary, using join buffer 제거하기'
excerpt: "쿼리 성능 개선하기"
title: '쿼리 성능 개선하기'
excerpt: "실행 계획을 확인하자"

categories:
- mysql
Expand Down Expand Up @@ -139,22 +139,22 @@ sql의 실행 계획은 아주 중요하고 성능을 개선할 때 아주 유
이렇게 여러 칼럼이 있습니다. 그 중 성능에 큰 영향을 미치는 칼럼 두 가지만 자세히 알아보겠습니다.

### Type
1. const : 쿼리에 Primary key 혹은 unique key 칼럼을 이용하는 where 조건절을 가지고 있고, 반드시 하나의 데이터를 반환하는 방식이다. (옵티마이저가 해당 부분은 상수로 처리하기 때문에 const라고 한다.)
2. eq_ref : 조인에서 Primary key 혹은 unique key 칼럼을 이용하는 where 조건절을 가지고 있고, 반드시 하나의 데이터를 반환하는 방식이다. (const와 다른 점은 eq_ref는 조인에서 사용된다는 점이다.)
3. ref : eq_ref와 다르게 join의 순서와 관계없이 사용된다. 그리고 primary key, unique key도 관계없다. 그냥 인덱스의 종류와 관계없이 `=` 조건으로 검색할 때 사용된다
4. fulltext: mysql 전문 검색 인덱스를 사용해서 레코드에 접근하는 방법, 전문 검색할 컬럼에 인덱스가 있어야 한다. "MATCH ... AGAINST ..." 구문을 사용해서 실행된다
5. range: 인덱스를 이용해서 검색하는데, 검색 조건이 `>, >=, <, <=, BETWEEN, IN()` 등의 연산자를 사용하는 경우이다. 보통의 인덱스 스캔이라고 하면 range, const, ref를 칭한다
6. index: 인덱스 풀 스캔이다. 인덱스를 이용해서 테이블의 모든 레코드를 읽는다. 인덱스를 이용해서 테이블을 읽는 것이기 때문에 all보다는 빠르다.
7. all: 테이블 풀 스캔이다. 테이블의 모든 레코드를 읽는다. 가장 느린 방법이다.
1. **const** : 쿼리에 Primary key 혹은 unique key 칼럼을 이용하는 where 조건절을 가지고 있고, 반드시 하나의 데이터를 반환하는 방식이다. (옵티마이저가 해당 부분은 상수로 처리하기 때문에 const라고 한다.)
2. **eq_ref** : 조인에서 Primary key 혹은 unique key 칼럼을 이용하는 where 조건절을 가지고 있고, 반드시 하나의 데이터를 반환하는 방식이다. (const와 다른 점은 eq_ref는 조인에서 사용된다는 점이다.)
3. **ref** : eq_ref와 다르게 join의 순서와 관계없이 사용된다. 그리고 primary key, unique key도 관계없다. 그냥 인덱스의 종류와 관계없이 `=` 조건으로 검색할 때 사용된다
4. **fulltext**: mysql 전문 검색 인덱스를 사용해서 레코드에 접근하는 방법, 전문 검색할 컬럼에 인덱스가 있어야 한다. "MATCH ... AGAINST ..." 구문을 사용해서 실행된다
5. **range**: 인덱스를 이용해서 검색하는데, 검색 조건이 `>, >=, <, <=, BETWEEN, IN()` 등의 연산자를 사용하는 경우이다. 보통의 인덱스 스캔이라고 하면 range, const, ref를 칭한다
6. **index**: 인덱스 풀 스캔이다. 인덱스를 이용해서 테이블의 모든 레코드를 읽는다. 인덱스를 이용해서 테이블을 읽는 것이기 때문에 all보다는 빠르다.
7. **all**: 테이블 풀 스캔이다. 테이블의 모든 레코드를 읽는다. 가장 느린 방법이다.

실행 계획에서 자주 보이는 type들만 성능이 좋은 순으로 정리해봤습니다.
실행 계획에서 자주 보이는 type들만 **성능이 좋은 **으로 정리해봤습니다.

### Extra
1. using filesort: 정렬을 위해 별도의 파일 정렬을 수행한다. 이는 인덱스를 사용하지 않고 정렬을 수행한다는 의미이다. 이는 성능에 좋지 않다.
2. using index: 인덱스만으로 쿼리를 처리한다. 이는 인덱스만으로 쿼리를 처리하기 때문에 성능이 좋다.
3. using join buffer: join이 되는 칼럼은 인덱스를 생성한다. 하지만 driven table에 적절한 인덱스가 없다면 driving table에 있는 모든 레코드를 읽어서 join을 수행한다. 그래서 이걸 보완하기 위해 driving table에 읽은 레코드를 임시 공간에 저장하는데 그 곳이 join buffer이다.
4. using temporary: 쿼리를 처리하기 위해 임시 테이블을 생성한다. 인덱스를 사용하지 못하는 group by 쿼리가 대표적인 예이다.
5. using where: mysql 엔진이 별도의 가공, 필터링 작업을 처리한 경우일 때만 나타난다. 범위 조건은 스토리지 엔진에서 처리되어 레코드를 리턴해주지만, 체크 조건은 mysql 엔진에서 처리된다.
1. **using filesort**: 정렬을 위해 별도의 파일 정렬을 수행한다. 이는 인덱스를 사용하지 않고 정렬을 수행한다는 의미이다. 이는 성능에 좋지 않다.
2. **using index**: 인덱스만으로 쿼리를 처리한다. 이는 인덱스만으로 쿼리를 처리하기 때문에 성능이 좋다.
3. **using join** buffer: join이 되는 칼럼은 인덱스를 생성한다. 하지만 driven table에 적절한 인덱스가 없다면 driving table에 있는 모든 레코드를 읽어서 join을 수행한다. 그래서 이걸 보완하기 위해 driving table에 읽은 레코드를 임시 공간에 저장하는데 그 곳이 join buffer이다.
4. **using temporary**: 쿼리를 처리하기 위해 임시 테이블을 생성한다. 인덱스를 사용하지 못하는 group by 쿼리가 대표적인 예이다.
5. **using where**: mysql 엔진이 별도의 가공, 필터링 작업을 처리한 경우일 때만 나타난다. 범위 조건은 스토리지 엔진에서 처리되어 레코드를 리턴해주지만, 체크 조건은 mysql 엔진에서 처리된다.


type뿐만 아니라 extra도 쿼리의 문제를 파악하는데 아주 큰 도움을 줍니다. 그 중 자주 보이는 것들에 대해서만 정리해봤습니다.
Expand Down

0 comments on commit ed1a3a3

Please sign in to comment.