2011-02-15 2 views
6

나는 명시만큼LEFT (외부) 조인을 사용하는 경우 조인의 테이블 순서가 중요합니까?

SELECT .... 
    FROM oranges 
     LEFT JOIN kiwis ON kiwis.orange_id = oranges.id, 
     bananas, 
     apples 
WHERE .... 

또는

SELECT .... 
    FROM bananas, 
     apples, 
     oranges 
     LEFT JOIN kiwis ON kiwis.orange_id = oranges.id 
WHERE .... 

처럼

SELECT .... 
    FROM apples, 
     oranges 
     LEFT JOIN kiwis ON kiwis.orange_id = oranges.id, 
     bananas 
WHERE .... 

이 절의 FROM 다른 순열 정확히 동일합니다 SQL 쿼리를 확인하고 싶습니다 오렌지와 키위 사이의 LEFT JOIN은 그대로 유지됩니다. 다양한 문서에서 읽은 것부터 반환 된 집합은 정확히 같아야합니다.

저는 실제로 쿼리의 결과에만 관심이 있습니다. 실제 데이터베이스에서는 성능이 떨어졌습니다. (나는 AFAIK가 조인 순서에 관한 옵티 마이저 힌트를 지원하지 않고 최적의 쿼리 계획을 자동으로 생성하려고 시도하는 PostgreSQL 8.3을 사용하고 있습니다.)

+0

테스트 해 보셨습니까? 'JOIN'의 순서는 이전의'JOIN'의 구체적인 결과가 필요하지 않는 한 무의미합니다 – Matthew

+0

바나나, 사과, 오렌지는 데카르트 제품입니까? 또는 "join-in-WHERE"절? – gbn

+1

EXPLAIN은 여러분에게 다음과 같이 보여줄 것입니다 : http://www.postgresql.org/docs/current/static/sql-explain.html 그리고 아무런 힌트도 없습니다. PostgreSQL은 꽤 영리합니다. –

답변

15

은 암시 적으로 CROSS JOINs와 동일하지만 불분명합니다. 명백한 JOINS를 사용하십시오.

WHERE 절에 합류하는 경우 조인과 필터가 섞여 있기 때문에 일 수는 일 수 있습니다.

SELECT .... 
    FROM apples a 
     JOIN 
     bananas b ON ... 
     JOIN 
     oranges o ON ... 
     LEFT JOIN 
     kiwis k ON k.orange_id = o.id 
WHERE (filters only) 

주 :

  • 내부 조인 크로스 조인은 교환 법칙이 성립와 연관됩니다 순서가 문제가 일반적으로하지 않습니다.
  • 외부 조인이 지정되지 않았습니다.
  • SQL은 선언적입니다. 옵티 마이저에게 옵티마이 저가 원하는대로, 수행 방법이 아니라고 알려줍니다. 이렇게하면 JOIN 순서 고려 사항이 제거됩니다 (이전 2 항목 적용).
+0

아주 훌륭하고 철저한 대답입니다. 감사드립니다. 레코드의 경우, 예, 조인 조건은 WHERE 절에 있습니다. 이것은 레거시 응용 프로그램이며 일부 쿼리를 리팩토링하는 중입니다. –

0

나는 당나귀 년 동안 SQL을 해왔으며, 모든 경험에서 테이블 순서는 중요하지 않습니다. 데이터베이스는 쿼리를 전체적으로 살펴보고 최적의 쿼리 계획을 만듭니다. 이것이 데이터베이스 회사가 쿼리 계획 최적화에서 PhD를 가진 많은 사람들을 고용하는 이유입니다.

데이터베이스 공급 업체는 사용자가 쿼리에서 SQL을 직접 나열한 순서에 따라 최적화 된 경우 상업적 자살을 범합니다.

+1

이전 버전의 DBMS가 실제로 그렇게했습니다 (예 : Oracle 7 & 8).이것은 정적으로 쿼리를보고 쿼리의 구조에 기반한 몇 가지 규칙을 적용하여 실행 계획을 결정할 때 일반적으로 "규칙 기반 최적화 프로그램"이라고 불립니다. 규칙 기반 옵티 마이저를 사용하면 첫 번째 테이블은 일반적으로 운전 테이블 이었으므로 주문에 성능에 큰 영향을 미쳤습니다 –

1

상황은 Controlling the Planner with Explicit JOIN Clauses에 요약됩니다. 외부 조인은 재정렬되지 않고 내부 조인이 될 수 있습니다. 그리고 쿼리를 실행하기 전에 * join_collapse_limit *를 삭제하고 특정 순서대로 원하는 옵티 마이저 순서를 지정할 수 있습니다. 그것이이 영역의 데이터베이스를 "힌트"하는 방법입니다.

일반적으로 EXPLAIN을 사용하여 어떤 주문을 받고 있는지 확인하기 위해 두 개의 쿼리가 동일한 계획을 얻고 있음을 시각적으로 확인하는 데 사용할 수 있습니다.

관련 문제