#title Outer Join [[TableOfContents]] ==== 뭔가가 잘못된 Outer Join ==== 많은 사이트의 ERD를 보면 관계란 가뭄에 콩 나듯 찾아 볼 수 있다. 관계의 중요성을 모르기 때문이다. 관계는 데이터의 연결을 의미하며, 개체간의 관계가 정의된다는 것은 업무의 정의를 의미하기도 한다. 관계는 데이터의 연결을 통한 또 다른 정보의 생성이다. 그러므로 단순한 정보만이 아닌 유용한 정보가 창출될 수 있다. 그런데 데이터 모델링을 할 때는 열심히 관계를 맺어주고, 실제 코딩에 들어가면 관계를 끊어 놓고 개발하는 경우가 많이 있다. 그것은 관계에 의해 삽입, 갱신, 삭제 작업에 제약이 걸려서 일 것이다. 그러나 이러한 방법은 상당히 안 좋은 개발방법이다. 열심히 정의를 해놓고, 개발할 때는 이것을 무시하면서 개발하는 하는 것이 된다. 즉, 현실과의 불일치를 나타내는 것이다. 묵시적으로 연결이 되어 있다고 하여, 그것이 모두 지켜질 수는 없는 노릇이기 때문이다. 그렇기 때문에 어떤 사이트에 가보면 SP내의 SQL문에서 90% 이상이 Left Outer Join 으로 연결되어 있었던 적도 있다. ERD좀 보자고 하면 관계가 잘 맺어져 있지만, 실제 구현된 것을 보면 관계라는 것은 전혀 찾아볼 수가 없다. 이것은 많은 시간과 노력을 기울여 정의해 논 구현 전 단계를 모두 무시하는 것이 되어 버린다. 이렇게 하여 제품이 출시되었을 때는 구현 전 단계에 들어가 비용과 노력은 낭비가 되어 버린 것과 같다. Outer Join이 필요한 경우는 슈퍼타입과 서브타입의 배타적인 관계의 경우에서 많이 나타난다. 또한 차집합을 구하는 경우도 그렇다. 그러나 일반적인 경우 Outer Join이 많이 나타난다면 전혀 현실을 반영하지 못한 것이 되며, 현실과의 일치성이 결여된 정보시스템에서 좋은 질을 가진 정보를 기대하기란 어려운 것이다. 다음은 Left Outer Join의 개념이다. Right Outer Join은 반대로 생각하면 될 것이고, Full Outer Join은 양쪽 모두 일치되지 않는 것들까지 결과집합으로 만든다. ==== Outer Join의 개념 ==== 개념은 무지 쉽다. 실제 예를 보면 쉽게 이해할 수 있을 것이다. {{{ USE pubs SELECT a.au_fname, a.au_lname, p.pub_name FROM authors a LEFT OUTER JOIN publishers p ON a.city = p.city ORDER BY p.pub_name ASC, a.au_lname ASC, a.au_fname ASC }}} attachment:outer_join01.jpg attachment:outer_join02.jpg Outer Join의 반드시 한 방향으로만 진행된다는 것이다. 앞의 예제에서 우리는 인덱스가 잡힌 컬럼을 임의로 변형하여 인덱스를 사용하지 못하게 하여, EMPLOYEE 테이블을 먼저 읽혀지도록 하였다. 그러나 다음과 같이 LEFT OUTER JOIN을 하면 어떻게 될까? 제아무리 발버둥쳐도 JOBS 테이블부터 읽혀진다. {{{ USE PUBS SELECT E.EMP_ID, E.FNAME + E.LNAME AS NAME, J.JOB_ID, J.JOB_DESC FROM JOBS J LEFT OUTER JOIN EMPLOYEE E ON RTRIM(E.JOB_ID) = J.JOB_ID --의도적인 컬럼의 변형으로 드라이빙 순서 바꿈 WHERE RTRIM(E.JOB_ID) = '5' AND J.JOB_ID = '5' }}} attachment:outer_join03.jpg 즉, 위에서 수행한 왼쪽 외부조인은 JOBS.JOB_ID = EMPLOYEE.JOB_ID 의 결과와 조건에 맞지 않아도 JOBS 테이블에 대한 SELECT 절에 명시한 내용은 모두 표시한다는 내용이다. 물론 EMPLOYEE 테이블에 대한 SELECT 절에 명시한 내용에 대한 값도 표시하고, 그 이외의 값에 대해서는 널값으로 처리한다. 우리는 이러한 것을 역이용하여 원하는 방향으로 조인을 유도할 수 있음을 알 수 있다. 물론 Suppressing을 해도 된다. 실행계획이 고정된다는 것은 Outer Join으로 인해 불리한 실행계획이 계속 사용될 수도 있다는 것이다. Outer Join의 경우 대부분 많은 양의 데이터를 가진 테이블에서 적은 양의 데이터를 가진 테이블로 연결을 하게 되는데 이러한 경우 Merge Join과 Hash Join으로 실행계획이 풀리는 것을 자주 볼 수 있다.