join 시 성능에 대한 이론적인 질문 0 2 2,094

by 웁스 [2011.12.27 15:18:07]


join 시 성능에 대한 이론적인 질문 좀 하겠습니다. 실제 테스트  DBMS는 MYSQL이지만 oracle과 별반 틀리지 않을 것 같아서 올립니다.


TEST1 테이블
id
1
2
TEST2 테이블
id  cnt
1  100건
1  100건
2  200건
2  200건
3  10000000건
3  10000000건
3  10000000건
3  10000000건
3  10000000건
3  10000000건
4  20000000건
4  20000000건
4  20000000건
4  20000000건
4  20000000건
TEST3 테이블
id  cnt
1  100건
1  100건
1  100건
2  200건
2  200건
3  10000000건
3  10000000건
3  10000000건
3  10000000건
3  10000000건
3  10000000건
3  10000000건
3  10000000건
3  10000000건
3  10000000건
4  20000000건
4  20000000건
4  20000000건
4  20000000건
4  20000000건
4  20000000건
4  20000000건
4  20000000건
4  20000000건
위와 같이 TEST1, TEST2, TEST3 세 개의 테이블이 존재합니다.
첫 번째 조인 방법
SELECT id, cnt
  FROM (
        SELECT id 
          FROM TEST1
       ) a LEFT OUTER JOIN
       (
       SELECT id
            , SUM(cnt) AS cnt
         FROM TEST2
        GROUP BY id
       ) b ON a.id = b.id LEFT OUTER JOIN
       (
       SELECT id
            , SUM(cnt) AS cnt
         FROM TEST3
        GROUP BY id
       ) c ON a.id = c.id
       
두 번째 조인 방법
SELECT id, cnt
  FROM (
        SELECT id 
          FROM TEST1
       ) a LEFT OUTER JOIN
       (
       SELECT id
            , SUM(cnt) AS cnt
         FROM TEST2 test2, TEST1 test1
        WHERE test2.id = test1.id
        GROUP BY id
       ) b ON a.id = b.id LEFT OUTER JOIN
       (
       SELECT id
            , SUM(cnt) AS cnt
         FROM TEST3 test3, TEST1 test1
        WHERE test3.id = test1.id
        GROUP BY id
       ) c ON a.id = c.id
      
첫 번째 방법은 TEST2, TEST3 테이블의 id를 기준으로 모든 데이터를 그룹바이 하는 것이고
두 번째 방법은 TEST2, TEST3 테이블을 TEST1 테이블과 조인한 후 새로운 집합의 데이터를 추출하여 그룹바이 하는 것 입니다.
실제 테스트를 해보면 별 차이가 없습니다.
단지 이론적으로는 두 번째 방법이 더 빠를 것이라는 판단이 들지만 TEST1 테이블을 세 번이나 select해야 하는 비용과 코드가 지저분해 보인다는 단점이 있다는 생각이 드네요.
만약 위와 같이 두 가지 케이스가 있다면 이론적으로 어느 쪽의 성능이 더 좋을까요?
아니면 위의 방법 외에 또 다른 쿼리 방법이 있는지도 여쭙고 싶습니다.
의견 부탁드립니다.
by 마농 [2011.12.27 16:22:07]
t1 에는 자료가 적고 t2와 t3에는 불필요한 자료가 많은 경우네요.
이 경우 버려질 자료들까지 모두 조회한 후 자료를 버린다면 비효율이죠.
그래서 생각하신 방법이 2번 방법인듯 보이네요. 좋은 시도입니다.
이 경우 1번 방법을 사용한다고 해도 조인 조건이
그룹바이 안으로 침투가 가능할수도 있읍니다.
실제 그런지는 속단하지 마시고 반드시 실행계획을 확인해 보셔야 하구요.

위와 같이 특수한 경우
(기준테이블이 건수가 한정적이고 비교테이블은 다량이며 불필요한 자료를 다수 포함할 경우)
라면 스칼라서브쿼리를 사용하는 방안이 좋을 듯 합니다.
물론 조인키에는 모두 인덱스가 있다고 가정합니다.

SELECT id
, (SELECT SUM(cnt) FROM test2 WHERE id = t1.id) cnt_1
, (SELECT SUM(cnt) FROM test3 WHERE id = t1.id) cnt_2
FROM test1 t1
;

by 웁스 [2011.12.27 17:06:41]
마농님 답변감사합니다.
스칼라 쿼리를 이용하는 방법이 있었네요.
그리고 "그룹바이 안으로 침투가 가능할 수도 있습니다." 라고 덧 붙여준 내용을 토대로 실행 계획을 뽑으며 다방면으로 테스트를 해보았으나 침투하는 현상은 없었습니다. mysql 옵티마이저가 센스가 없어서 그런 건지..제가 그 무엇인가를 빠트리고 있는 건지는 알 수 없지만 결론은 SQL 쿼리는 가독성 보다 성능에 더 비중을 둬야 겠다는 결론이 나네요. ^^
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입