DB 성능차이에 대한 Tips
DB 성능을 조정하기 위한 여러가지 꿀팁들이 있겠지만 여기서 한 번 최대한 정리해보려한다.
1. 서브쿼리보다 join을 이용하는 것이 보통 더 빠르다!
그래서 보통 서브쿼리랑 JOIN문이 같이 있는 쿼리의 경우 더 빨리 끝나는 JOIN을 먼저 처리하고 서브쿼리는
나중에 처리하는 것이 좋다고 한다.
# 예시
select
a.* # 더 빨리 나오는 JOIN문을 먼저 처리하였다.
, (SELECT count(*) test FROM testDB WHERE a.id = b.id)
# 이렇게 생긴 것이 서브쿼리
from
(SELECT
테이블1,컬럼1,
테이블2,컬럼2,
테이블3,컬럼3,
...
FROM
테이블1
join 테이블2 # 조인문
on 테이블1.컬럼1 = 테이블2.컬럼2
join 테이블3
on 테이블1.컬럼1 = 테이블3.컬럼3
) a
[서브쿼리란?]
외부 쿼리(메인 쿼리) 내부에 있는 내부쿼리, 쿼리안에 쿼리가 들어간 것
서브쿼리 만으로 연산이 가능한 경우가 있고 서브쿼리가 메인쿼리의 열에 의존하는 경우가 있다.
물론 모든 경우에 사용할 수는 없겠지만 아래와 같은 경우에선 사용해볼 수 있을 것이다!
예시를 통해 알아보자
ex)
테스트를 위한 가벼운 생성문
CREATE TABLE test.Student ( id INT PRIMARY KEY NOT NULL AUTO_INCREMENT, name VARCHAR(50) NOT NULL, class_id INT NOT NULL);
CREATE TABLE test.Class (
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL
);
INSERT INTO test.Student (id, name, class_id)
VALUES (1, '알렉스', 1), (2, '듀크', 3);
INSERT INTO test.Class (id, name)
VALUES (1, '생물학'), (2, '지리학'), (3, '수학');
Student 테이블
id | name | class_id |
1 | 알렉스 | 1 |
2 | 듀크 | 3 |
Class 테이블
id | Name |
1 | 생물학 |
2 | 지리학 |
3 | 수학 |
학생들이 듣고있는 강의의 이름을 알고 싶은 경우
서브쿼리:
SELECT name
FROM test.Class
WHERE test.Class.id = (
SELECT class_id FROM test.Student WHERE test.Class.id = test.Student.class_id
);
연산 결과는 다음과 같다.
name |
생물학 |
수학 |
서브쿼리는 직관적이지만 메인쿼리의 id(class의 id)와 서브쿼리의 id(Student의 class_id)를 매칭해주는 작업을 위해
class의 id 개수만큼 서브쿼리가 실행되므로 메인쿼리의 수가 많다면 효율적이지 못하다고 할 수 있다.
그래서 이런 경우엔 JOIN을 사용하는 것이 효율적이라고 한다.
JOIN:
SELECT c.name
FROM test.Class AS c
JOIN test.Student AS s
ON c.id = s.class_id;
Plus) 문득 궁금해서 각각의 학생들이 어떤 강의를 듣는지 출력해보려 했다.
JOIN을 쓸 경우
SELECT c.name, s.name
FROM test.Class AS c
JOIN test.Student AS s
ON c.id = s.class_id;
결과는 다음과 같다
name | name |
생물학 | 알렉스 |
수학 | 듀크 |
그런데 위 JOIN을 사용한 쿼리문을 JOIN없이 서브쿼리로 대체할 수는 없는 걸까?
궁금해서 아래와 같은 쿼리문을 시도해보았다.
SELECT c.name,
(SELECT name
FROM test.Student s
WHERE s.class_id = c.id) AS student_name
FROM test.Class c;
하지만 그 결과는 다음과 같았다.
name | name |
생물학 | 알렉스 |
지리학 | null |
수학 | 듀크 |
이는 어쨌든 Class의 모든 네임에 대해 서브쿼리를 실행하므로 '지리학'의 경우엔 null 값이 나오는 것이다.
이 쿼리를 어떻게 손보고 있지만 아직 찾지 못해 추후 좀 더 찾아보아야겠다.
출처:
https://kimsyoung.tistory.com/entry/SUBQUERY-%EC%99%80-JOIN-%EC%9D%98-%EC%B0%A8%EC%9D%B4-%E4%B8%8A
https://www.w3schools.com/sql/sql_join_left.asp