복붙노트

[SQL] ON 대 WHERE 절 가입하여

SQL

ON 대 WHERE 절 가입하여

나는 다음과 같은 T-SQL 코드가 있다고 가정 :

SELECT * FROM Foo f
INNER JOIN Bar b ON b.BarId = f.BarId;
WHERE b.IsApproved = 1;

다음 하나는 동일한 행 집합을 반환합니다 :

SELECT * FROM Foo f
INNER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);

이 여기에 최상의 경우 샘플을하지 않을 수 있지만,이 두 가지 사이의 성능 차이가 있습니까?

해결법

  1. ==============================

    1.아니, 쿼리 최적화 프로그램은 두 예제에 대해 동일한 실행 계획을 선택하는 스마트 충분하다.

    아니, 쿼리 최적화 프로그램은 두 예제에 대해 동일한 실행 계획을 선택하는 스마트 충분하다.

    당신은 실행 계획을 확인하는 SHOWPLAN를 사용할 수 있습니다.

    그럼에도 불구하고, 당신은 모두가 WHERE 절에 ON 절에 연결하고 모든 제한을 가입 놓아야합니다.

  2. ==============================

    2.그냥 외부 조인과의 차이에주의. (오른쪽 테이블, 바) b.IsApproved의 필터가의 ON 조건에 추가되는 쿼리 가입 :

    그냥 외부 조인과의 차이에주의. (오른쪽 테이블, 바) b.IsApproved의 필터가의 ON 조건에 추가되는 쿼리 가입 :

    SELECT * 
    FROM Foo f 
    LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId); 
    

    WHERE 절에 필터를 배치 동일하지 않습니다 :

    SELECT * 
    FROM Foo f 
    LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
    WHERE (b.IsApproved = 1); 
    

    에 대한 '실패'외부 바 조인 이후의 (a f.BarId에 대한 b.BarId이없는 경우 즉)이 이러한 모든 가입 실패 행을 NULL로 b.IsApproved을 떠날 것이며, 이러한 행은 필터링됩니다.

    이 바라 보는 또 다른 방법은 첫 번째 질의에 대해, 왼쪽 외부의 b 바 가입이다 (b.IsApproved = 1)과 (b.BarId = f.BarId) LEFT OUTER이 보장되므로 가입 이후 항상 왼쪽 테이블 행을 반환합니다 왼쪽 테이블 행은 실패에 가입하는 경우에도 반환됩니다. 그러나, 조건에 가입 좌 OUTER로 (b.IsApproved = 1)의 첨가 효과는 오른쪽 테이블 컬럼 NULL 출력되는 경우 (b.IsApproved = 1) 일반적으로 좌측에인가 된 동일한 규칙에 따라, 즉 거짓 (b.BarId = f.BarId)에 가입 조건.

    최신 정보: 콘래드가 자주 묻는 질문을 완료하려면, 옵션 필터에 해당하는 LOJ은 다음과 같습니다

    SELECT * 
    FROM Foo f 
    LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
    WHERE (b.IsApproved IS NULL OR b.IsApproved = 1);
    

    절은 가입 여부를 조건 모두를 고려할 필요가 즉 실패 (NULL)과 필터는 무시하고, 조인 경우는 성공하고 필터를 적용해야합니다. (b.IsApproved 또는 b.BarId은 NULL 검사를 할 수 있습니다)

    나는이 가입하기에 b.IsApproved 필터 상대의 다양한 게재 위치의 차이점을 설명하는 여기에 함께 SqlFiddle을 넣었습니다.

  3. ==============================

    3.

    SELECT * FROM Foo f
    INNER JOIN Bar b ON b.BarId = f.BarId
    WHERE b.IsApproved = 1;
    

    이 갈 수있는 더 좋은 형태입니다. 읽기 쉽고 쉽게 수정할 수 있습니다. 비즈니스 세계에서 이것은 당신이 가고 싶은 것입니다. 지금까지 성능으로 그들은 같은 생각입니다.

  4. ==============================

    4.나는했습니다 최적화도 MSSQL의 최신 버전에 스마트 충분하지 않았다 경우를 보인다 - 그리고 성능 차이는 괴물이었다.

    나는했습니다 최적화도 MSSQL의 최신 버전에 스마트 충분하지 않았다 경우를 보인다 - 그리고 성능 차이는 괴물이었다.

    하지만이 시간 SQL 서버 최적화 대부분의 문제를 해결하고 올바른 계획을 얻을 것이다하는 예외입니다.

    그래서 절 및 최적화가 필요한 경우 WHERE에 필터를 사용하는 정책을 유지한다.

  5. ==============================

    5.난 그냥 네 개의 테이블에 대한 쿼리의 테스트 실행 - 한 기본 테이블 세 INNER 조인과 네 paramters의 총과 비교의 ON에서 필터 기준을 사용하여 두 가지 접근 방식의 실행 계획 (도에서 다음 가입하고, WHERE 절).

    난 그냥 네 개의 테이블에 대한 쿼리의 테스트 실행 - 한 기본 테이블 세 INNER 조인과 네 paramters의 총과 비교의 ON에서 필터 기준을 사용하여 두 가지 접근 방식의 실행 계획 (도에서 다음 가입하고, WHERE 절).

    실행 계획은 정확히 동일합니다. 나는 SQL 서버 2008 R2에 달렸다.

  6. from https://stackoverflow.com/questions/10297231/where-clause-vs-on-when-using-join by cc-by-sa and MIT license