DB/SQL

MYSQL SELECT 튜닝

호두밥 2021. 10. 10. 16:58

인데스 칼럼의 변형 제거하기

다음처럼 WHERE 조건에서 인덱스 칼럼 값에 변형이 가해진 경우는 인덱스를 사용하지 못해 비효율적입니다.

인덱스 칼럼에 변형을 제거해주어야 합니다.

 

[튜닝 전]

SELECT A, B, C FROM T WHERE PK1/100 = 1;

[튜닝 후]

SELECT A, B, C WHERE PK1 BETWEEN 100 AND 199;

 

다음은 WHERE 조건에서 인덱스 칼럼 2개를 합쳐서 사용한 경우입니다. 이도 마찬가지로 인덱스 칼럼에 변형이 가해졌기 때문에 인덱스를 사용하지 못해 비효율적입니다. 

 

[튜닝 전]

SELECT A, B, C FROM TABLE WHERE CONCAT(A,B) = '202107';

[튜닝 후]

SELECT A, B, C FROM TABLE A = '2021' AND B = '07';

필요없는 함수 제거하기

다음은 값이 NULL인 경우 0으로 바꾸어 결과를 합산해주도록 한 쿼리입니다.

SUM을 수행할 때는 NULL이면 값을 계산에 포함시키지 않기 때문에 IFNULL 함수를 넣어주지 않아도 됩니다.

 

[튜닝 전]

SELECT SUM(IFNULL(A, 0)) FROM TABLE;

[튜닝 후]

SELECT SUM(A) FROM TABLE;

필요 없는 DISTINCT 제거하기

모든 데이터가 고유한데, DISTINCT가 들어가 있다면 필요없는 중복제거 연산이 수행되어 비효율적입니다.

*중복제거 연산에는 키워드가지고 데이터를 순서데로 나열해가며 중복값을 제거하는 정렬이 수행된다.

 

[튜닝 전]

-- A가 PK
SELECT DISTINCT A, B, C FROM TALBE WHERE TYPE = 'a';

[튜닝 후]

SELECT A, B, C FROM TALBE WHERE TYPE = 'a';

 

 UNION 대신 UNION ALL을 사용할 수 있는지를 판단해 바꿔주는 것이 좋습니다.

 

[튜닝 전]

SELECT A, B, C FROM TABLE WHERE TYPE = 'A'
UNION 
SELECT A, B, C FROM TABLE WHERE TYPE = 'B'

[튜닝 후]

SELECT A, B, C FROM TABLE WHERE TYPE = 'A'
UNION ALL
SELECT A, B, C FROM TABLE WHERE TYPE = 'B'

 

인덱스 순서를 고려하지 않은 쿼리 수정하기

인덱스는 구성 칼럼의 순서대로 정렬된 데이터를 가지고 있습니다. 인덱스를 사용할 때 칼럼 순서를 고려하지 않으면 인덱스를 호율적으로 사용할 수 없습니다.

예를 들어 INDEX 구성 칼럼의 순서가 A,B로 되어있습니다.

다음은 GROUP BY 절에 인덱스 칼럼의 순서를 고려하지 않고 작성된 쿼리입니다.

 

[튜닝 전]

SELECT A, B, COUNT(1) 
FROM TABLE
GROUP BY A, B
;

* INDEX 구성

* 실행계획

다른 칼럼 없이 인덱스 구성 칼럼인 A, B로만 이루어져 있어 테이블에 접근하지 않고 인덱스에만 접근하였습니다.( Using Index) 그러나 인덱스 칼럼의 순서를 고려하지 않아서 B, A순으로 다시 정렬했습니다. (Using Temporary)

A,B로 그룹핑 하는 것과 B,A로 그룹핑 하는 것이 결과에 차이를 주지 않기 때문에 Group by절의 칼럼 순서를 A,B로 바꾸었습니다.

 

[튜닝 후]

SELECT A, B, COUNT(1) 
FROM TABLE
GROUP BY B, A

 

 

'DB > SQL' 카테고리의 다른 글

MySQL 조인 JOIN 튜닝 : 불필요한 조인을 EXISTS로 바꾸기  (0) 2021.10.10
MySQL 쿼리 정리  (0) 2021.10.10
MySQL 데이터 타입 Data Types  (0) 2021.10.10
MYSQL 실행계획 EXPLAIN  (0) 2021.10.08
MYSQL 힌트  (0) 2021.10.07