이 SQL 문에서 이중 내부 조인을 사용하는 이유는 무엇입니까?


10

이 레거시 SQL 쿼리를보고 있습니다. 얻을 수없는 비트는 동일한 열에서 동일한 테이블을 두 번 내부 결합하는 이유입니다. Table1과 Table1이 별칭 "Table1Alias"와 결합 된 것에 대해 이야기하고 있습니다.

SELECT DISTINCT othercolumns,
                Table1Alias.columna
FROM   maintable
       INNER JOIN secondarytable
               ON maintable.id1 = secondarytable.a_id1
       INNER JOIN table1
               ON secondarytable.id2 = table1.id3
       INNER JOIN table1 Table1Alias
               ON secondarytable.id2 = Table1Alias.id3
       INNER JOIN thirdtable
               ON table1.id4 = thirdtable.id5
       INNER JOIN fourthtable
               ON thirdtable.id6 = fourthtable.id7
       INNER JOIN fivetable
               ON thirdtable.id8 = fivetable.id9
       INNER JOIN sixthtable
               ON Table1Alias.columna = sixthtable.id10
       LEFT JOIN seventhtable
              ON thirdtable.id11 = seventhtable.id12
WHERE  LEFT(secondarytable.type123, 2) BETWEEN '01' AND '09'
       AND secondarytable.type456 = 'cate'
       AND table1.type = '0'
       AND Table1Alias.columna = 'conn'

답변:


27

다음과 같이 쿼리를 다시 작성하는 것이 도움이 될 수 있습니다. 따라서 2 개의 조인이 다른 것입니다 .

FROM   maintable 
       INNER JOIN secondarytable 
               ON maintable.id1 = secondarytable.a_id1 
       INNER JOIN table1 
               ON secondarytable.id2 = table1.id3 
              AND table1.type = '0' 
       INNER JOIN table1 Table1Alias 
               ON secondarytable.id2 = Table1Alias.id3 
              AND Table1Alias.columna = 'conn' 
       INNER JOIN
       ...
WHERE  LEFT(secondarytable.type123, 2) BETWEEN '01' AND '09' 
       AND secondarytable.type456 = 'cate' 

조인 후에 적용되는 위치가 아닙니다. 즉, 이러한 제약 조건이 조인 문의 일부인 경우 (예 : AND로 연결되어 있음) 동의하지만 모든 경험에서 WHERE는 행을 필터링하는 조인의 결과에 적용됩니다. 실제 조인에 영향을 미치지 않는 조인 된 테이블
Frank Hopkins

3
@Darkwing 내가 아는 한, 최상의 최적화 계획을 세우는 것이 쿼리 최적화 프로그램의 역할이므로 조건을 어디에 두는지는 중요하지 않습니다. 그러나 조인 옆에두면 더 읽기 쉬워 지지만 의견 일뿐입니다.
Mathematics

조인 후에 발생하더라도 조인 결과는 결국 다릅니다. 예, 일반적으로 결합 된 행은 성능을 향상시키기 때문에 결합하기 전에 필터링됩니다.
Gherman

1
또한 하위 쿼리와 결합하는 것과 같습니다 (예 :) INNER JOIN (SELECT * FROM table1 WHERE type = 0) table1. 그러면 무슨 일이 일어나고 있는지 더욱 분명해질 수 있습니다.
Barmar

3
@Mathematics-조건이 ON조인 절에 있는지 또는 WHERE절에 있는지 여부는 조인이 인 경우 큰 문제가 될 수 있습니다 OUTER JOIN. ON절 에서 조건이 실패하면 기본 행은 여전히 ​​일치하는 외부 행없이 포함됩니다. WHERE절 에서 실패하면 기본 행이 결과 세트에서 제외됩니다.
RDFozz

8

where절을 보면 ,가 가리키는 행 table1은 열 type이 '0'이고,가 가리키는 행 table1alias은 열 columna이 ''conn '이어야합니다.

아마도 table1같은 행에 여러 행이 id3있습니까?


2

테이블 구조를 보지 않고 접근하는 방법은 더 작은 비 커버링 인덱스를 사용하고 더 큰 커버링 인덱스에서 테이블에 조인하여 '키 조회'작업을 피하고 기존 인덱스를 수정하지 않도록 나머지 행을 얻는 것입니다. (또는 색인을 수정할 수없는 경우)


2

복잡한 조인에서 테이블이 두 번 이상 나타날 때마다 일반적으로 둘 이상의 관계에 참여하는 엔터티가 있기 때문입니다. @Ypercube가 준 대답으로 판단하면 여기에 해당됩니다.

엔티티와 관계는 일반적으로 데이터의 의미와 기본 주제와의 연결을 통해 이해됩니다. 레거시 시스템을 신중하게 구축 한 경우에는 주제를 분석하고 각 데이터 요소를 신중하게 정의하기 위해 약간의주의가 필요했습니다. 그들은 엔티티 관계 모델을 구축했을 수도 있습니다. 신중한 작업이 모두 손실되었을 수 있으며 과거를 파헤쳐 서 재구성해야합니다. 이것은 고고학과 비슷합니다.

Table1과 같은 테이블 이름을 사용하면 주제의 작동 방식에 대한 실마리가 없습니다. 이름이 설명 적이라하더라도 시스템의 주제에 대한 우리의 이해는 귀하의 경우에 필요한 것과 매우 다를 수 있습니다. 그것은 당신에게 달려 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.