어느 가을날의 전환점

ORACLE|JOIN 성능 - 일반적으로 크기가 작은 테이블이 먼저 드라이빙 되는 것이 빠르다. 본문

Database/Oracle

ORACLE|JOIN 성능 - 일반적으로 크기가 작은 테이블이 먼저 드라이빙 되는 것이 빠르다.

어느가을빛 2010. 7. 28. 19:57
일반적으로 조인을 할 때, 예를들어 A와 B를 조인할 때 크기가 작은 쪽에서 큰 쪽으로 데이터가 흘러가는게 빠릅니다.

예를들어 보겠습니다.

<테이블 EMP>
NO EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
1 7369 SMITH CLERK 7902 1980-12-17 800   20
2 7499 ALLEN SALESMAN 7698 1981-02-20 1600 300 30
3 7521 WARD SALESMAN 7698 1981-02-22 1250 500 30
4 7566 JONES MANAGER 7839 1981-04-02 2975   20
5 7654 MARTIN SALESMAN 7698 1981-09-28 1250 1400 30
6 7698 BLAKE MANAGER 7839 1981-05-01 2850   30
7 7782 CLARK MANAGER 7839 1981-06-09 2450   10
8 7788 SCOTT ANALYST 7566 1982-12-09 3000   20
9 7839 KING PRESIDENT   1981-11-17 5000   10
10 7844 TURNER SALESMAN 7698 1981-09-08 1500.1 0 30
11 7876 ADAMS CLERK 7788 1983-01-12 1100   20
12 7900 JAMES CLERK 7698 1981-12-03 950   30
13 7902 FORD ANALYST 7566 1981-12-03 30001   20
14 7934 MILLER CLERK 7782 1982-01-23 1300   10


<테이블 DEPT>
NO DEPTNO DNAME LOC
1 10 ACCOUNTING NEW YORK
2 20 RESEARCH DALLAS
3 30 SALES CHICAGO
4 40 OPERATIONS BOSTON


위에 2개의 테이블이 있는데 나그네님께서 말씀하신 첫번째 쿼리를 보겠습니다.

SELECT A.EMPNO,
             B.DEPTNO
FROM   EMP  A,
            DEPT B
WHERE  A.DEPTNO = B.DEPTNO
AND       A.DEPTNO IN (10, 20);

여기서 보시면 A.DEPTNO IN (10, 20) 으로 인해 A 테이블이 먼저 상수를 받습니다. 그리고 상수화된 DEPTNO를 DEPT 테이블에 넘겨주죠(조인)
이 과정을 일반적으로 A 테이블이 드라이빙 걸렸다고 하는데요. 이 쿼리가 처리하는 전체 로우수를 보겠습니다.

참고로 여기서 말씀드리는 로직은 Full Scan을 기준으로 설명드립니다.(Full Scan은 인덱스 없이 테이블 전체를 뒤져보는 로직입니다.)

/*********************************************************************/
/* 1. 첫번째 쿼리 분석                                                                         */
/*********************************************************************/
A.DEPTNO IN (10, 20) 를 통해 EMP 테이블에 (10, 20)인 데이터를 찾습니다. 그럼 EMP 테이블이 총 14 로우수이기 떄문에 전체를 다 뒤지므로 14가 됩니다. --- ①
그리고 (10)을 찾아봤더니 3개 로우가 검색되었습니다. --- ②
이 3개의 로우를 가지고 A.DEPTNO = B.DEPTNO 이 과정을 통해 DEPT 테이블에 (10)이 있는지 찾아봐야겠죠? 만족하는 로우는 1개 이지만 전체를 다 뒤져야 되므로 4번을 찾습니다. --- ③

그리고 (20)에 대해서도 마찬가지로 ②, ③ 번 과정을 거쳤더니 5번, 4번이 나왔습니다.

이를 토대로 (10, 20)에 대해 만족하는 로우를 찾기위해 검색한 총 로우수는 14 + (3 * 4) + (5 * 4) = 46 이 됩니다.

/*********************************************************************/
/* 2. 두번째 쿼리 분석                                                                         */
/*********************************************************************/
이제 두번째를 보도록 하겠습니다.

SELECT A.EMPNO,
       B.DEPTNO
FROM   EMP  A,
       DEPT B
WHERE  A.DEPTNO = B.DEPTNO
AND    B.DEPTNO IN (10, 20);


두번째는 EMP부터 상수를 받는게 아니라 B.DEPTNO IN (10, 20) 이것처럼 DEPT부터 상수를 받았네요. 이를 통해 1번에서 했던 과정을 반복해보면 다음과 같은 값이 나옵니다.

DEPT에서 (10, 20)을 찾기 위해 검색한 총 로우수 : 4
(10)을 가지고 EMP에서 찾기 위해 검색한 총 로우수 : 1 * 14
(20)을 가지고 EMP에서 찾기 위해 검색한 총 로우수 : 1 * 14

-> 4 + (1 * 14) + (1 * 14) = 32 이 됩니다.

여기서 보셨다시피 상수로 받는 테이블(드라이빙 테이블)이 조회조건에 의해 만들어진 집합 결과가 작은 쪽이 더 유리하다는 것을 알 수 있을 것입니다.
현재는 EMP와 DEPT테이블에 데이터가 얼마 없어서 첫번째 쿼리와 두번째 쿼리의 응답속도 차이를 별로 못 느끼실테지만 100만건만 넘어가도 확연한 차이를 느끼실 수 있을겁니다.
더 자세한 내용을 원하시면 '새로쓴 대용량 데이터베이스 솔루션' 책을 사셔서 공부하시면 될 것 같습니다.

출처 : http://database.sarang.net
Comments