JOIN 키워드 사용 여부


45

다음 SQL 쿼리는 동일합니다.

SELECT column1, column2
FROM table1, table2
WHERE table1.id = table2.id;

SELECT column1, column2
FROM table1 JOIN table2 
ON table1.id = table2.id;

그리고 내가 시도한 모든 DBMS에 대해 동일한 쿼리 계획이 발생합니다.

그러나 나는 종종 한 사람이 다른 사람보다 확실히 낫다는 의견을 읽거나 듣습니다. 당연히, 이러한 주장은 결코 설명으로 입증되지 않습니다.

내가 일하는 곳에서 두 번째 버전은 다른 개발자들 대부분이 선호하는 것처럼 보이므로 놀람을 최소화하기 위해 해당 스타일을 선호합니다. 그러나 내 마음에, 나는 정말로 첫 번째 것을 생각하고 있습니다.

이러한 형태 중 하나가 다른 형태보다 객관적으로 더 낫습니까? 그렇지 않다면, 다른 것을 사용하는 이유는 무엇입니까?


1
왜 그것을 프로파일 링하고 나머지 사람들에게 결과를 알려주지 않습니까? 일반적으로 성능은 스타일 선호보다 훨씬 높습니다.
데미안 브레히트

3
"내가 시도한 모든 DBMS에 대해 동일한 쿼리 계획에 따른 결과"성능 측면에서 답이있을 수 있다면 stackoverflow.com에 요청했을 것입니다. 아아, 그들은 같은 쿼리입니다.
SingleNegationElimination 1

아 .. 그리워 :)
Demian Brecht

2
"주관적"은 "당신의 의견은 무엇입니까"를 의미하지 않습니다. FAQ 에서 제시 한 기준 충족시키기 위해 이것을 편집했습니다 .
Aaronaught

나는 또한 당신이 당신 자신의 질문에 대답했다고 생각 하는 놀라움을 최소화하기 위해 그 스타일로 경향이 있습니다. 놀람은 나쁘다.
Pieter B

답변:


60

두 번째 형태가 더 낫다는 것을 알았습니다. 그게 내가 배운 방식 때문일 수도 있지만, 인정할 것이지만, 우려의 분리라는 구체적인 이유가 하나 있습니다. where 절에서 테이블을 조인하는 데 사용하는 필드를 넣으면 쿼리 이해가 어려울 수 있습니다.

예를 들어 다음 쿼리를 사용하십시오.

select *
from table1, table2, table3, table4
where table1.id = table2.id
and table2.id = table3.id
and table3.id = table4.id
and table1.column1 = 'Value 1'

위의 쿼리에는 테이블 조인 조건과 실제 비즈니스 로직 조건이 모두 단일 공간으로 결합되어 있습니다. 큰 쿼리를 사용하면 이해하기가 매우 어려울 수 있습니다.

그러나 이제 다음 코드를 사용하십시오.

select *
from table1 join table2 on table1.id = table2.id
join table3 on table2.id = table3.id
join table4 on table3.id = table4.id
where table1.column1 = 'Value 1'

이 경우, 테이블과 관련이 있거나 테이블과 관련이있는 모든 항목은 from 절과 분리되며 조회 제한에 대한 실제 비즈니스 로직은 where 절에 있습니다. 나는 그것이 더 큰 쿼리의 경우 훨씬 이해하기 쉽다고 생각합니다.


이 방법은 특히 두 개의 테이블을지나거나 왼쪽, 오른쪽 및 전체 조인 조합이 필요한 경우 특히 합리적인 방법입니다.
aglassman

5
. 절은 관심있는 데이터의 하위 집합 지시 여기서 "의 분리"를 +1은 함께 가져 데이터를 조인

39

조인 구문은 1992 년에 이전 쉼표 구문을 대체했습니다. 현재 쉼표 구문으로 코드를 작성할 이유가 없습니다. 당신은 아무것도 얻지 못하고 명시 적 구문에는없는 몇 가지 문제가 있습니다.

우선 복잡한 쿼리를 얻을 때 where 조건을 누락하여 실수로 교차 조인을 수행하는 것이 매우 쉽습니다. 이것은 구문 오류가 발생하므로 명시 적 조인 구문이 발생하지 못하게 할 수있는 것입니다.

교차 조인을 계획하는 경우 암시 적 구문에서 유지 관리를 수행하는 사람이 where 절을 추가하지 않은 것으로 가정 할 수 있지만 명시 적 조인 구문은이를 명확하게합니다.

그런 다음 암시 적 구문을 사용하는 적어도 일부 db에서 문제가되는 왼쪽 및 오른쪽 조인 문제가 있습니다. SQL Server에서는 더 이상 사용되지 않으며 실제로 이전 버전에서도 정확한 결과를 반환하지 않습니다. 외부 조인이 필요한 쿼리는 SQL Server에 암시 적 구문을 포함하지 않아야합니다.

또한 사람들이 암시 적 및 명시 적 조인을 혼합 할 때 (예 : 왼쪽 조인을 추가 할 때) 잘못된 결과가 발생하는 여기 및 다른 사이트에서 질문을 보았으므로 혼합하는 것은 좋지 않습니다.

마지막으로 암시 적 조인을 사용하는 많은 사람들은 실제로 조인을 이해하지 못합니다. 데이터베이스를 효과적으로 쿼리해야한다는 중요한 이해입니다.


설명 주셔서 감사합니다. 내가 가르쳐 졌을 때 우리는 두 가지 구문을 모두 보았지만 그 차이점은 설명하지 않았다. 때로는 누락 된 부분이있는 쿼리를 생성 할 수있었습니다.
awiebe

8

하아. 방금 PostgreSQL 설명서를 보면서 내 질문에 대한 가능한 대답을 찾았습니다 . 이 페이지에서 설명하는 내용을 요약하면 결과 쿼리는 여전히 동일하지만 옵티마이 저가 고려해야 할 계획 의 수는 조인 수에 따라 기하 급수적으로 증가합니다.

약 6 번의 조인 후에는 쿼리를 계획하는 시간이 눈에 띄게 많아서 약 10 일 후에 옵티마이 저가 철저한 계획 검색에서 확률 적 검색으로 전환하여 최적의 계획에 도달하지 못할 수 있습니다 .

런타임 매개 변수를 설정하면 명시 적으로 언급 된 내부 및 교차 조인을 암시 적 조인과 다르게 처리하여 다른 옵션을 탐색하지 않고 계획의 맨 위에 강제하도록 계획 할 수 있습니다.

참고로, 기본 동작은 두 경우 모두 동일하며, 대체 계획을 얻으려면 dbms의 내부 및 해당 테이블의 특성에 대한 지식이 필요하므로 다른 결과를 얻습니다.


2
그러나 해당 문서를 약간 잘못 이해했습니다. 첫째, 실제로 세 가지 임계 값이 있습니다. 하나는 당신이 지적한대로 GEQO를 발사; 다른 두 개 (시작 및 축소 축소 한계)로 인해 대패 질이 결합 순서를 재구성하는 것이 아니라 적용 가능한 색인을 선택하게됩니다. 두 번째로 그리고 마찬가지로, 쿼리는 구문 분석 될 때 다시 작성됩니다. 이로 인해 첫 번째 예제 쿼리가 두 번째 쿼리 트리와 정확히 동일한 쿼리 트리로 구문 분석됩니다. 임계 값은 PG에게 조인 순서를 다시 정렬해야하는지 여부를 알려줍니다.
Denis de Bernardy

8

여기에 설정된 이론적 견해가 있습니다 :

쉼표를 사용하여 두 개 이상의 테이블 이름을 구분하면 직교 곱이됩니다. '왼쪽'테이블의 모든 행은 오른쪽 테이블의 모든 행과 '일치'(연결)됩니다.

where 절에 무언가를 쓰면이 '연결'에 조건을 설정하여 어떤 행을 어떤 행과 '연결'해야하는지 알려주는 것과 같습니다.

이것은 실제로 행에 "결합"하는 것이므로 더 읽기 쉬운 구문을 제공하는 데 도움이되는 join 키워드는 일반적인 값에 대한 결합을 원한다는 것을 더 잘 이해할 수 있습니다. @Dustin이 위에서 설명한 것과 유사합니다.

이제 모든 DBMS는 현명합니다. 즉, 직교 곱을 먼저 계산 한 다음 데이터를 필터링 (매우 낭비)하는 것이 아니라 쿼리 구조를 기반으로합니다. 내가 생각할 수있는 유일한 것은 당신이 그것을 '참가'하도록 요청할 때 그것은 결합 활동을 명시 적으로 만드는 것과 같으며 아마도 코드를 더 빨리 실행하는 데 도움이 될 것입니다 (얼마나 많은 양입니까? 쉼표로 구분 된 경우 최적의 전략을 '수집'하는 데 시간이 필요합니다. 나는 틀릴 수도 있지만, 어떻게 코딩 할 것인지에 대해 교육받은 추측을하고 있습니다 ...


5

일반적으로 해당 경우에 JOIN 문을 사용하는 것이 좋습니다.

미래에 명령문을 INNER JOIN에서 OUTER JOIN으로 변경해야하는 상황이 발생하면 두 번째 명령문으로 수행하기가 훨씬 쉬워집니다.


3

모든 RDBMS는 그것들을 실행 측면에서 동일한 것으로 만들 것입니다. 그것은 더 읽기 쉽고 표현적인 것인지에 달려 있습니다.

JOIN을 사용하면 다음과 같이 조인 일치 항목과 실제 ​​선택 항목이 명확 해집니다.

select name, deptname
from people p, departments d
where p.deptid = d.id and p.is_temp = 'Y'

vs.

select name, deptname
from people p
    inner join departments d on p.deptid = d.id
where p.is_temp = 'Y'

후자의 경우 결합 조건과 선택 기준이 무엇인지 즉시 알 수 있습니다.


1

나는 한 번만 두 가지 결과가 다른 최적화 세트를 보았으며 메모리가 제공되면 실제로 털이 많은 쿼리에서 ms-sql2k에있었습니다. 이 예에서 * =와 함께 사용 된 이전 형식은 약 4 배 빠른 성능을 제공했습니다. Microsoft 기술 담당자를 포함하여 아무도 이유를 설명 할 수 없었습니다. MS 사람들은 그것을 실수라고 표시했습니다. 나는 다시는 본 적이 없다.

대부분의 RDBMS는 전체 데카르트를 수행 할 수 없을 정도로 똑똑하기 때문에 내가 그것을 사용하지 않을 것이라고 생각할 수있는 가장 큰 이유는 (감가 상각되지 않음) 30-35 세 미만의 사람들이 내가 본 적이없는 것입니다. 이전 양식을 발견하고 그들이 만나면 심하게 잃어 버립니다.


물론 왼쪽 조인 구문은 정확한 결과를 안정적으로 제공하지 못했기 때문에 (SQL Server 2000의 경우 BOL 참조) 더 빠르더라도이를 대체했을 것입니다.
HLGEM

나는 그것을 결코 겪지 않았고 별표로 검색하는 것이 결코 끝나지 않습니다. 예가 있습니까?
Bill

-1

이전 스타일은 더 이상 사용되지 않으므로 사용해서는 안됩니다.

더 좋은지 아닌지에 대한 논쟁조차 없어야합니다. 새 코드는 이전 구문을 사용하지 않아야합니다.


나는이 답변이 더 이상 사용되지 않고 사용되어서는 안되는지 말하지 않고는 아무것도 추가하지 않는다고 생각합니다 .
RemcoGerlich

1
더 이상 사용되지 않는 이유 @RemcoGerlich는 여기서 논의되지 않습니다. 여기서 논의되는 것은 이전 구문을 사용할지 새로운 구문을 사용할지입니다. 하나가 다른 것보다 낫든 그렇지 않든간에 헛소리가 있습니다 : 오래된 구문을 사용해서는 안됩니다. 질문은 또 다른 토론입니다. (20 년 전에 정착 한 회사)
Pieter B

-4

더 간결한 구문의 한 가지 이유는 더 간결하기 때문에 읽기가 더 쉽다는 것입니다. 장황한 사례는 COBOL에서 산술을 쓰는 것과 비슷하다고 생각합니다.


Downvoters :이 응답에 실제로 부정확 한 것이 있습니까?
Adam Libuša
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.