2009-04-24 3 views
30

JOIN에 대한 ON 절의 기준을 어떤 방식으로 정렬합니까? 성능에 미치는 영향은JOIN의 ON 절에서 참조되는 테이블의 순서가 중요합니까?

select a.Name, b.Status from a 
inner join b 
on b.ID = a.StatusID 

select a.Name, b.Status from a 
inner join b 
on a.StatusID = b.ID 

있습니까? 여러 기준이 있다면 어떻게 될까요?

하나의 주문을 다른 주문보다 유지 관리 할 수 ​​있습니까?

답변

33

JOIN 순서는 FROM 절에 올바른 순서로 테이블을 넣어 강제 할 수 있습니다

  1. MySQL 주문 물질을 만드는 STRAIGHT_JOIN라는 특별한 조항이있다.

    b.id에 인덱스 사용합니다 :

    SELECT a.Name, b.Status 
    FROM a 
    STRAIGHT_JOIN 
         b 
    ON  b.ID = a.StatusID 
    

    을 그리고이 a.StatusID에 인덱스 사용합니다 :

    SELECT a.Name, b.Status 
    FROM b 
    STRAIGHT_JOIN 
         a 
    ON  b.ID = a.StatusID 
    
    • OracleJOIN 순서를 시행하는 특별한 힌트 ORDERED 있습니다

    이것은 b.id에 인덱스를 사용하거나 b에 해시 테이블을 구축 할 것입니다 :

    SELECT /*+ ORDERED */ 
         * 
    FROM a 
    JOIN b 
    ON  b.ID = a.StatusID 
    

    을 그리고 이것은 aa.StatusID에 인덱스를 사용하거나 해시 테이블을 구축 할 것입니다 :

    SELECT /*+ ORDERED */ 
         * 
    FROM b 
    JOIN a 
    ON  b.ID = a.StatusID 
    
    • SQL ServerFORCE ORDER이라는 힌트가 있습니다.

    b.id에 인덱스를 사용하거나 b에 해시 테이블을 구축 할 것입니다 :

    SELECT * 
    FROM a 
    JOIN b 
    ON  b.ID = a.StatusID 
    OPTION (FORCE ORDER) 
    

    을 그리고 이것은 aa.StatusID에 인덱스를 사용하거나 해시 테이블을 구축 할 것입니다 :

    SELECT * 
    FROM b 
    JOIN a 
    ON  b.ID = a.StatusID 
    OPTION (FORCE ORDER) 
    
    • PostgreSQL 얘들 아, 미안. 귀하의 TODO list는 말한다 :

      최적화 힌트는 최적화 문제를 피해 갈 (안 원)

    최적화 힌트를 사용합니다. 차라리 문제가보고되고 수정 될 것입니다.

비교의 순서에 관해서는, 어떤 RDBMS에 문제가되지 않습니다

, AFAIK.

필자는 개인적으로 항상 어떤 열을 검색 할 것인지를 예측하고 왼쪽에이 열을 넣으려고합니다 (lvalue처럼 보일 수 있습니다).

자세한 내용은 this answer을 참조하십시오.

+2

위대한 답변! +1 –

+1

공식 TODO http://wiki.postgresql.org/wiki/Todo#Features_We_Do_Not_Want에서 "PostgreSQL guys, sorry"- "Optimizer Hints"에 관해서. –

+0

@Milen : 죄송합니다 다시 :) – Quassnoi

8

아니요.

제 2의 예는 제가 읽기 쉽도록하기위한 것입니다.

5

아니요. 데이터베이스는 전체 조건을 기반으로 최상의 실행 계획을 결정해야하며 순서대로 각 항목을보고 만들어야합니다. 두 쿼리에 대한 실행 계획을 요청하면이를 확인할 수 있습니다. 두 쿼리가 동일하다는 것을 알 수 있습니다 (동일한 논리를 궁극적으로 지정하는 경우 매우 다른 쿼리라도 동일한 실행 계획으로 컴파일되는 경우가 많습니다).).

1

아니요. 하루가 끝나면 a = b인지 여부 만 평가하게됩니다.

그리고 평등의 대칭 속성으로

상태 : 어떤 양의 a와 b를 들어

  • 을, a = b라면, B는 =.

(12)*=12 또는 12=(12)*을 확인하면 논리적으로 차이가 없습니다.

값이 같으면 참여하지 말고 참여하지 마십시오. 그리고 첫 번째 예에서와 같이 지정했는지 또는 두 번째 예 에서처럼 지정했는지 여부에 따라 차이가 없습니다.

1

Read this

SQLSERVER 훨씬 더 복잡한 이것보다 상황에 대한 최적화가 포함되어 있습니다. 여러 기준이있는 경우

물건을 평가 일반적으로 게으른 (하지만 난 어떤 경우 가장자리의 경우 주위에 약간의 연구를 할 필요가있다.)

쉽게 읽을

나는 보통 내가 생각

SELECT Name, Status FROM a 
JOIN b 
ON a.StatusID = b.ID 

를 선호 선언 된 것과 동일한 순서로 변수를 참조하는 것이 더 좋지만 실제로는 개인적인 취향입니다.

1

유일한 이유 나는 두 번째 예제를 사용하지 않을 :

select a.Name, b.Status 
from a 
inner join b 
    on b.ID = a.StatusID 

사용자가 다시 와서 말할 가능성이 '나는 모두 볼 수있는 a.name의 그들은 더 상태 기록이없는 경우에도? ' '이름 기록이없는 경우에도 b.status를 모두 볼 수 있습니까?'라는 문구가 있으므로이 예를 미리 계획하기 위해 LEFT 외부 조인을 예상하여 On a.StatusID = b.ID을 사용합니다. 이것은 'b'없이 테이블 'a'레코드를 가질 수 있다고 가정합니다.

수정 : 결과가 변경되지 않습니다.

사용자가 요구 사항을 변경하고 싶지 않으므로 이는 아마 부적절한 요소 일 수 있습니다.

+1

LEFT 또는 RIGHT 조인에서는 순서가 중요하지 않으므로 실제로 변경되지 않습니다. 내가 볼 수있는이 사건. ON 절이 "b.ID = a.StatusID"인 경우에도 절을 LEFT OUTER JOIN으로 변경할 수 있습니다. –

+1

@Tom -이 점을 지적 해 주셔서 감사합니다. 나는 거의 공황 발작이 있었다. –

0

아니요, 중요하지 않습니다. 그러나 여기에서 별도의 줄에 각 테이블 참조는 별도의 줄에

select a.*, b.* 
from tableA a 
    inner join tableB b 
      on a.name=b.name 
       and a.type=b.type 

(적어도 나에게) 쿼리를 읽기 쉽게 만들 수 있도록 예를 들어, 그리고 각각의 기준을 가입 할 수 있습니다. 탭을 사용하면 어떤 항목에 속하는지 유지할 ​​수 있습니다.

내가하고 싶은 또 다른 일은 내 진술에 내 기준을 테이블과 같은 순서로 흐르게하는 것입니다. 그래서 a가 처음이고 b가되면, a는 왼쪽에 있고 b는 오른쪽에있을 것입니다.

1

많은 사람들이 다음과 같이 말했습니다. 순서는 결과 나 성능에 차이를 만들지 않습니다.

내가 지적하고자하는 것은 LINQ to SQL은 첫 번째 경우에만 허용합니다.! 예는, 예를 들어 다음은 잘 작동

...

var result = from a in db.a 
      join b in db.b on a.StatusID equals b.ID 
      select new { Name = a.Name, Status = b.Status } 

...이 Visual Studio에서 오류가 발생합니다 때 :

이 컴파일러 오류가 발생
var result = from a in db.a 
      join b in db.b on b.ID equals a.StatusID 
      select new { Name = a.Name, Status = b.Status } 

:

  • CS1937 : 이름 '이름'을 '의 왼쪽에 범위에 있지 같음 '. 'equals'의 양쪽에서 표현식을 교환하는 것을 고려하십시오.
  • CS1938 : 이름 'name'이 (가) 'equals'의 오른쪽 범위에 없습니다. 'equals'의 양쪽에서 표현식을 교환하는 것을 고려하십시오.

표준 SQL 코딩과는 관련이 없지만이 중 하나에 익숙해지면 고려해야 할 사항입니다.

관련 문제