SQL JOIN vs IN 성능?


164

JOIN 또는 IN을 사용하면 올바른 결과를 얻을 수있는 경우가 있습니다 ... 일반적으로 더 나은 성능을 가진 이유는 무엇입니까? 실행중인 데이터베이스 서버에 따라 얼마나 달라 집니까? (참고로 나는 MSSQL을 사용하고 있습니다)


:) 나는 실제로 얼마 전에 비슷한 것을 연구 할 때 사용한 다른 기사를 찾고 있었고 실수로 그 기사를 우연히 발견했습니다.
AdaTheDev

가능한 속죄 미안 ... 내가 검색 할 때 그 질문을 찾지 못했습니다
Polaris878

답변:


196

일반적으로, IN그리고 JOIN다른 결과를 얻을 수있는 다른 쿼리입니다.

SELECT  a.*
FROM    a
JOIN    b
ON      a.col = b.col

와 같지 않다

SELECT  a.*
FROM    a
WHERE   col IN
        (
        SELECT  col
        FROM    b
        )

b.col고유 하지 않으면 .

그러나 이것은 첫 번째 쿼리와 동의어입니다.

SELECT  a.*
FROM    a
JOIN    (
        SELECT  DISTINCT col
        FROM    b
        )
ON      b.col = a.col

조인 열이 UNIQUE이와 같이 표시되어 있으면 두 쿼리 모두에서 동일한 계획을 생성합니다 SQL Server.

그렇지 않은 IN경우 JOINon 보다 빠릅니다 DISTINCT.

성능에 대한 자세한 내용은 내 블로그에서이 기사를 참조하십시오.


예, 조인 열이 고유 한 경우 (내 경우에) 동일하게 실행된다는 점이 합리적입니다.
Polaris878

1
비슷한 메모에서 IN (SELECT DISTINCT ...) 또는 단순히 IN (SELECT ...)을 사용해야합니까?
moo

8
@ orlandu63 : IN의미합니다 DISTINCT. SQL Server그것을 알아 차릴만큼 똑똑하고 두 쿼리에 대해 동일한 계획을 생성합니다. 그러나 다른 사람 RDBMS의 행동 방식은 확실하지 않습니다 .
Quassnoi

>> IN 및 JOIN은 다른 결과를 생성 할 수있는 다른 쿼리입니다. b.col이 고유하지 않더라도이 경우에 다른 결과를 생성하는 이유를 설명해 주시겠습니까?
Abhijeet



6

어느 쪽이 더 잘 작동하는지 알아 보려면 실제로 실행 시간을 프로파일 링해야합니다.

일반적으로 외래 키 열에 인덱스가 있고 INNER JOIN 조건 만 (또는 대부분) 사용하는 경우 JOIN이 약간 빠를 것이라고 생각합니다.

그러나 OUTER JOIN을 사용하기 시작하거나 외래 키 인덱스가 부족하면 IN이 더 빠를 수 있습니다.

마크


나도 이것을 생각하고 있었다. 왜냐하면 JOIN이 더 일반적인 경우이고 최적화 될 가능성이 높기 때문이다.
Polaris878

4

논리적 차이에 대한 흥미로운 글 : SQL Server : JOIN vs IN vs EXISTS-논리적 차이

관계와 인덱스가 유지된다고 가정하면 Join이 전반적인 성능을 향상시킬 것입니다 (다른 작업보다 더 많은 노력을 기울이는 노력). 개념적으로 생각하면 2 개의 쿼리와 1 개의 쿼리의 차이점입니다.

쿼리 분석기에 연결하고 시도하여 차이점을 확인해야합니다. 또한 쿼리 실행 계획을보고 단계를 최소화하십시오.


4

이 스레드는 꽤 오래되었지만 여전히 자주 언급됩니다. 내 개인적인 취향에 대해서는 조금 더 불완전합니다. 왜냐하면 EXISTS 키워드를 사용하여 데이터베이스에 더 빠르지 않은 것으로 자주 묻는 또 다른 방법이 있기 때문입니다.

따라서 테이블 a의 값에만 관심이 있다면이 쿼리를 사용할 수 있습니다.

SELECT  a.*
FROM    a
WHERE   EXISTS (
    SELECT  *
    FROM    b
    WHERE   b.col = a.col
    )

db가 col에서 같은 값을 갖는 b에서 모든 레코드를 찾을 필요가 없기 때문에 col이 색인화되지 않으면 차이가 클 수 있습니다. 첫 번째 레코드 만 찾으면됩니다. b.col에 인덱스가없고 ba 테이블 스캔에 많은 레코드가있는 경우 결과가 발생할 수 있습니다. IN 또는 JOIN을 사용하면 전체 테이블 스캔이되고 EXISTS를 사용하면 부분 테이블 스캔 만됩니다 (첫 번째 일치 레코드가 발견 될 때까지).

b에 동일한 열 값을 갖는 많은 레코드가있는 경우 조건을 만족시키기 위해 이러한 레코드를 모두 임시 공간으로 읽는 데 많은 메모리를 낭비하게됩니다. 존재하면 일반적으로 피할 수 있습니다.

인덱스가 있어도 EXISTS가 IN보다 빠릅니다. 데이터베이스 시스템 (최적화 프로그램), 데이터 및 마지막으로 사용되는 인덱스 유형에 따라 다릅니다.


3
MSSql에서는 존재하는 것이 IN보다 낫다는 것이 사실이 아닙니다. 자세한 정보 : Explainextended.com/2009/06/16/in-vs-join-vs-exists 여기에서 읽을 수있는 내용은 다음과 같습니다. "EXISTS는 한 행만 리턴하기 때문에 EXISTS가 IN보다 효율적이라고 생각합니다. 위의 예에서 볼 수 있듯이 EXISTS와 IN은 정확히 동일한 계획을 생성합니다 .EXISTS가 IN보다 융통성이 있기 때문입니다. IN은 항상 EXISTS로 다시 작성할 수 있습니다 (Equijoin과 함께 간단한 WHERE 조건 사용) ) 그러나 그 반대의 경우는 아닙니다. "
Micaël Félix

3

각 데이터베이스의 구현이지만 아마도 공통적 인 문제가 거의 같은 방식으로 해결된다고 추측 할 수 있습니다. MSSQL을 사용하는 경우 생성 된 실행 계획을 살펴보십시오. 프로파일 러 및 실행 계획을 설정하여이 작업을 수행 할 수 있습니다. 이것은 명령을 실행할 때 텍스트 버전을 제공합니다.

사용중인 MSSQL 버전이 확실하지 않지만 쿼리 분석기의 SQL Server 2000에서 그래픽 버전을 얻을 수 있습니다. 이 기능이 이후 버전의 SQL Server Studio Manager에서 어딘가에 숨어있을 것입니다.

실행 계획을 살펴보십시오. 물론 테이블이 작은 경우가 아니라면 테이블 스캔을 피하십시오.이 경우 테이블 스캔이 인덱스를 사용하는 것보다 빠릅니다. 각기 다른 시나리오가 생성하는 다른 조인 작업을 읽으십시오.


1

옵티마이 저는 일반 쿼리에 대해 동일한 결과를 제공 할 수있을 정도로 똑똑해야합니다. 실행 계획을 확인하면 동일한 것을 제공해야합니다. 그렇지 않으면 일반적으로 JOIN이 더 빠르다고 생각합니다. 그러나 모든 시스템이 다르므로 시스템의 코드를 프로파일 링해야합니다.


5
해야 할 것? 아마도. 그렇습니까? 아니요. 내 게시물을 참조하십시오.
cletus
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.