우리는 프로젝트를 하면서 수많은 쿼리를 작성하게 됩니다. 하지만 동일한 결과를 가져오더라도, 수행하는 시간은
다를 수 있습니다. 쿼리문을 효율적으로 짜기 위해 피해야할 것들은 무엇이 있을까요?
1. Select 문에 * 쓰지 않기
<나쁜 예시>
SELECT *
FROM member
<좋은 예시>
SELECT id, age, name
FROM member
불러오는 필드값이 많을 수록 DB는 더 많은 부담을 지게 됩니다. 칼럼 중에 꼭 필요한 필드만 가져올 수 있도록 SELECT 문에 * 사용을 지양해야 합니다.
2.Like 검색어에 변수 앞 %를 피하기
보통 조건문을 많이 쓰는 칼럼의 경우 최대한 결과를 빨리 찾기 위해 인덱스를 걸어두는데, 변수 앞에 다음과 같이
%를 두게 되면 인덱스를 사용하지 않고 테이블 Full Scan을 하게 된다고 합니다. 따라서 아래 작성된 SQL과 같이 (IN)을 사용하거나 다른 방법을 사용해야 Full Scan을 피하고 효율적인 검색을 할 수 있게 됩니다.
<나쁜 예시>
SELECT name, rating, director, actor, genre
FROM movie
WHERE genre LIKE "%Comedy"
<좋은 예시>
SELECT name, rating, director, actor, genre
FROM movie
WHERE genre IN ("Romantic Comedy", "Comedy",)
3. Where에 여러 조건이 있을 경우 왼쪽에 중복도가 낮은 칼럼을 배치하기
Where 검색을 사용할 경우 And로 묶어서 여러 조건에 부합하는 데이터를 찾는 경우가 있습니다. 이럴 때는 조건문에서 제일 먼저 오는 칼럼을 변경이 되지 않고 다른 데이터와 중복되지 않는 칼럼을 선택하는 것이 좋습니다. 제일 먼저 오는
조건에서 대부분의 데이터들이 걸리지기 때문입니다. 보통 카디널리가 높은(중복도가 낮은) 칼럼에 인덱스를 거는데,
해당 칼럼에 인덱스를 거는 것도 성능을 더 향상 시킬 수 있는 방법입니다.
4. Group By를 통한 연산시에는 Having보다 Where문을 쓰기
특정 조건에 부합하는 칼럼들을 묶어 합계나 평균같은 연산을 수행할 때 Having절을 사용하기도 합니다. 하지만, 쿼리
실행 순서에서 Where절이 Having절보다 먼저 실행되기 때문에 Group By에서 다뤄야하는 데이터가 작아져 효율적인
연산이 가능합니다.
<나쁜 예시>
SELECT m.id, COUNT(r.id) AS rating_cnt, AVG(r.value) AS avg_rating
FROM movie m
INNER JOIN rating r
ON m.id = r.movie_id
GROUP BY id
HAVING m.id > 1000;
<좋은 예시>
SELECT m.id, COUNT(r.id) AS rating_cnt, AVG(r.value) AS avg_rating
FROM movie m
INNER JOIN rating r
ON m.id = r.movie_id
WHERE m.id > 1000
GROUP BY id ;
5. DB에 별도의 연산을 거는 작업을 하지 않기
Where절에 특정 연산 조건을 만족하는 데이터를 찾기 위해 연산 과정을 그대로 넣을 경우 인덱스가 걸려있다 하더라도
해당 연산과정을 수행하기 위해 Table Full Scan이 발생하게 됩니다. 따라서 가급적 DB에는 별도의 연산 과정을 넣지
않는 것이 좋습니다.
<나쁜 예시>
SELECT id, name, price
FROM Item
WHERE FLOOR(price/2) = 2
<좋은 예시>
SELECT id, name, price
FROM Item
WHERE price BETWEEN 4 AND 5
이상으로 쿼리문을 사용할 때 성능을 향상시킬 수 있는 방법에 대해 살펴봤습니다.
글 읽어주셔서 감사합니다!
참고 자료
✅ 쿼리 최적화 첫걸음 — 보다 빠른 쿼리를 위한 7가지 체크 리스트
DB에 대한 데이터 분석가의 에티켓
medium.com
'DB' 카테고리의 다른 글
DB 인덱스 실습 (0) | 2023.05.31 |
---|---|
옵티마이저란? (0) | 2023.05.19 |
식별관계와 비식별관계 (0) | 2023.03.28 |
DB Index에 대하여 (0) | 2023.03.10 |
Transaction(트랜잭션)이란 (0) | 2023.01.01 |