SQL 쿼리문을 짤 때 join
을 통하여 여러 테이블에서 정보를 가져온다.
이때, n개
의 테이블을 join한다고 하면, n개의 테이블의 모든 컬럼과 모든 데이터를 조회
하므로 join하는 테이블의 개수가 많아질 수록 속도가 느려진다.
물론 데이터양이 많아도 쿼리의 속도는 현저하게 느려진다.
만약 밑과 같은 쿼리의 JOIN 성능을 개선하려면 어떻게 해야할까?
SELECT
MC.description
FROM ((Items I inner join ScrapItems SI on I.itemId = SI.itemId)
inner join ScrapBooks SB on SB.scrapBookId = SI.scrapBookId)
inner join MiniCategories MC on MC.miniCategoryId = I.miniCategoryId
WHERE SB.userId = 1
GROUP BY MC.description;
위의 쿼리는 4개의 테이블이 join
되어 있다. 위 쿼리는 Items 테이블, ScrapItems 테이블, ScrapBooks 테이블, MiniCategories 테이블에 존재하는 모든 컬럼과 데이터들을 읽어온다. 따라서 쿼리가 많이 느려질 수 밖에 없다.
이 쿼리를 어떻게 개선할 수 있을까?
SELECT
MC.description
FROM (((SELECT itemId, miniCategoryId FROM Items) I inner join (SELECT itemId, scrapBookId FROM ScrapItems) SI on I.itemId = SI.itemId)
inner join (SELECT scrapBookId, userId FROM ScrapBooks) SB on SB.scrapBookId = SI.scrapBookId)
inner join (SELECT miniCategoryId, description FROM MiniCategories) MC on MC.miniCategoryId = I.miniCategoryId
WHERE SB.userId = 1
GROUP BY MC.description;
위와 같이 join과 조회에 필요한 컬럼만을 선택하여 join 시키는 것이다.
왜 아래의 쿼리문의 성능이 더 좋을까?
SQL에서 조인 연산을 수행할 때 내부적으로 선택되는 알고리즘은 크게 3가지가 있다.
(1) Nested Loops Join (2) Hash Join (3) Sort Merge Join이 있다.
이때 Nested Loops Join이 다른 결합 알고리즘의 기본이 된다. 이때,Nested Loops Join
은중첩 반복
을 사용하는 알고리즘이다.
결국에는 Nested Loops Join
을 사용하면 join의 실행시간은 R(T1) R(T2) R(T3) ... R(Tn)에 비례하게 되는 것이다. (이때 R(Tn)은 Tn 테이블의 레코드 수이다.)
즉, 구동 테이블(Driving Table)이 작을 수록, 내부 테이블(Inner Table)의 결합키 필드에 인덱스가 존재할 때
join의 성능을 개선할 수 있다.
따라서 인덱스
와 테이블들의 컬럼을 지정하여 크기를 줄이면
join 성능을 개선할 수 있다.