JOIN 절에서 구문을 사용하면 특정 상황에서 최적화 장벽이 발생할 수 있습니까?


34

쿼리 에서 USING(대신에 ON) 구성 이 특정 경우 최적화 장벽을 도입 할 수 있다는 점에 주목했습니다 .FROMSELECT

나는이 핵심 단어를 의미한다 :

고르다 *
에서
b를 가입 USING (A_ID)

좀 더 복잡한 경우.

문맥 : 이 댓글이 질문에 .

나는 이것을 많이 사용 하고 지금까지 아무것도 발견하지 못했습니다. 영향이나 추가 정보에 대한 링크 를 보여주는 테스트 사례 에 매우 관심이 있습니다 . 나의 수색 노력이 비었습니다.

완벽한 대답은 보여주기 위해 테스트 케이스가 될 것 USING (a_id)대안에 비해 절에 가입 할 때 열등한 성능 ON a.a_id = b.a_id- 경우 가 실제로 발생할 수 있습니다.


2
@ kgrittn : 그것은 지금까지 일반적으로 기대했던 것 입니다. 결과 행렬에서 열이 하나 줄어듦에 따라 USING약간 빠릅니다 . 귀하의 조사 결과는 2005 년과 2008 년으로 거슬러 올라갑니다. 지금까지 문제가 해결되었다고 가정합니다. 그러나 가능한 제한 사항을 알 USING수 있습니다 . 결과 결합 열이 조인트 제품이므로 JOIN을 순서대로 적용 해야 할 수도 있습니다 . 따라서 JOIN 재정렬 옵션이 잠재적으로 제한됩니다.
Erwin Brandstetter

1
조인에 대한 USING 조건을 가진 VIEW가 dump / restore에 문제를 일으킬 수 있기 때문에이 스레드를 내가 자주 사용하지 못하게하는 것과 관련이있을 수있는이 스레드를 발견했습니다. archives.postgresql.org/pgsql- bugs / 2011-06 / msg00030.php 해결 방법이 ON을 사용하는 USING과 관련된 성능 문제와 관련된 또 다른 스레드가 여전히 남아 있다고 생각합니다.하지만 찾기를 포기할 것입니다. 뷰 외부에서 사용하는 것이 안전하고 쿼리가 느린 경우 진단 단계로 대신 ON을 시도하는 것을 기억하십시오.
kgrittn

1
"사용"하는 것으로 코드를 약간 읽을 수있게 만드는 것처럼 보이지만 두 필드 모두 동일한 이름이 필요하다고 생각합니다. DB가 어쨌든 일치해야하기 때문에 사용이 "on"보다 성능이 더 우수 할 것이라고 생각하지 않습니다. 선택이 조인과 동일한 성능을 갖는 것과 같습니다 (잘못된 경우 수정). 차이점은 Join이 더 깨끗하고 유지 관리하기 쉽다는 것입니다.
jcho360

2
@ HLGEM : 그것은 단지 상징적 인 이름이며, 예에서와 같이 두 개의 테이블 만 있으면 혼란의 여지가 없습니다. 아직도, 나는 그 질문을 수정했다. 불행히도 id열 이름으로 사용하는 것을 권장하지 않습니다 .
Erwin Brandstetter 2016 년

2
@ChristiaanWesterbeek : 동의하지 않습니다. 은 "이동-에 장소"포스트 그레스의 대답에-수심 입니다 (아직) 메일 링. SO에서 활동하는 Postgres 개발자는 극소수이지만 모든 Postgres 개발자와 전문가는 메일 링리스트를 읽습니다
a_horse_with_no_name

답변:


12

어윈 : 저는 엄격한 주문을 유발하는 사용이 최적의 계획을 배제 할 수있는 많은 경우를 만들 수 있다는 생각에 동의합니다. 나는 최근에 그의 쿼리에서 이와 같은 것을 가진 누군가를 도왔다 :

LEFT JOIN ( 
     a 
     JOIN b ON a.id = b.a_id
     JOIN c ON b.c_id = c.id
) ON a.id = something.a_id
LEFT JOIN (
     table1 t1
     JOIN table2 t2 ON t1.some_field = t2.other_field
     JOIN talbe3 t3 ON t2.yafield = t3.something_else
) ON ....
repeat a few more times

그의 경우 최악의 조인 블록은 약 2 만 번 (약 20 만 번) 행을 통해 중첩 루프 조인을 일으켰으며 (키워드를 수행 할 수 없음) 키를 인덱스로 푸시 할 수 없으므로 순차적 스캔이었습니다. 따라서 계단식 계획 변경으로 인해 전체 쿼리를 실행하는 데 약 3 시간이 걸렸습니다. 왼쪽 조인을 배포하면 키를 눌렀을 수 있으며 쿼리는 몇 초 만에 실행되었습니다. 물론 이것은 정확히 동등한 것은 아니기 때문에 플래너가 그것들을 동등한 것으로 취급 할 수 없기 때문에 그 계획을 해시 조인으로 파악한 다음 중첩 루프를 수행하는 것이 고통 스럽습니다.

특정 순서로 조인을 엄격하게 수행 할 때마다 계획 실행시 ​​키 필터 정보를 아직 사용할 수없는 경우가 발생하므로 빠른 인덱스 스캔 / 해시 조인에서 나중에 수행 할 수있는 작업이 발생합니다. 중첩 된 루프 / 순차 스캔에서 훨씬 느려질 수 있으므로 위의 조각이 즉시 동일하지는 않지만 동일한 문제를 나타냅니다.

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