2010-01-14 5 views
93

다음 중 더 효율적인 것은 무엇입니까?
나는 항상 을 사용하는 것에 대해 신중을 기했습니다. SQL Server가 결과를 큰 IF 문으로 바꾸기 때문입니다. 큰 결과 세트의 경우 성능이 저하 될 수 있습니다. 작은 결과 세트의 경우 어느 것이 좋을 지 확신하지 못합니다. 큰 결과 세트의 경우 EXISTS이 더 효율적이지 않습니까?SQL Server IN 대 EXISTS 성능

WHERE EXISTS (SELECT * FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2) 

대 올바른 보장

WHERE bx.BoxID IN (SELECT BoxID FROM Base WHERE [Rank = 2]) 
+6

알아내는 가장 좋은 방법은 그것을 밖으로 시도하고 몇 meassurements 할 수 있습니다. –

+10

거기에 ** 이걸로 gazillion 중복 될 수있어 ...... –

+0

@ marc_s : 예,하지만 저는 그것이 정말로 대소 문자에 의존한다고 생각합니다. 나는 정답은 klausbyskov (또는 선행 기술을 주장 할 수있는 사람)라고 생각합니다. – RedFilter

답변

117

EXISTS가 빨라집니다 참된.
IN으로 추가 처리를하기 전에 하위 쿼리의 모든 결과를 수집합니다.

+3

좋은 지적입니다. IN 문을 사용하려면 SQL Server가 완전한 결과 집합을 생성 한 다음 생각하는 큰 IF 문을 작성해야합니다. –

+63

이것은 사실 이었지만 현재 버전 (적어도 2008 년)에서는 옵티마이 저는 훨씬 더 똑똑합니다 ... 실제로는 EXISTS()와 마찬가지로 IN()을 처리합니다. –

+10

@Aaron - 예, 일반적으로 최적화 프로그램은 내부적으로보다 나은 계획을 수립합니다. 그러나 내부 바로 가기를 사용하면보다 복잡한 시나리오에서 해를 끼칠 수 있습니다. –

-1
내 머리 위로 떨어져

하지 : 나는 두 번째는 빨리이 경우가 될 전망이다.

  1. 첫 번째로 상관 된 하위 쿼리는 하위 쿼리가 각 행에 대해 실행되도록합니다.
  2. 두 번째 예에서 하위 쿼리는 상관 관계가 없으므로 한 번만 실행해야합니다.
  3. 두 번째 예에서 일치 항목을 찾으면 바로 IN이 단락됩니다.
3

실행 계획은 일반적으로 이러한 경우에 동일하지만 인덱스의 다른 모든 측면에서 옵티마이 저가 고려하는 방법을 알기 전까지는 실제로 알 수 없습니다.

33

SQL Server 2005 및 2008에서 일부 테스트를 수행했으며 EXISTS 및 IN 모두에서 동일한 다른 실제 실행 계획과 함께 돌아 왔습니다. Optimizer가 최적입니다. :)

무언가가 존재, 인디애나하지만 알고, 당신은 바로 쿼리하지 구절을 할 경우 가끔 다른 결과를 반환 할 수 있습니다 가입하기 : http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx

1

매우 문자 그대로의 EXISTS을 최적화하기 위해; 무언가가 거기에 있어야하지만 실제로 상관 관계가있는 하위 쿼리에서 반환 된 데이터는 필요하지 않습니다. 부울 조건 만 평가하는 것입니다. 그래서

:

WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)

상관 서브 쿼리 RBAR이므로 첫 번째 결과 히트 조건에 해당하게, 그리고 더 이상 처리되지 않는다.

+0

당신이 당신의 NULL 처리에 매우 신중하지 않은 경우 나는 놓친 또는 왜곡 된 결과를 얻는 것이 매우 쉽기 때문에 항상 LEFT JOIN + NULL 코딩을 사용할 때 매우 신중할 것입니다. 나는 매우 드물게 EXISTS 또는 CTE (누락 된 데이터에 대한 중복 삽입 또는 합성 삽입을 찾는)가 동일한 요구 사항을 충족하지 않고 LEFT JOIN + NULL을 능가하지 못하는 것을 발견했습니다. –

+2

TOP 1은 완전하지 않거나 이벤트 리던던시). EXISTS는 일치하는 행을 찾으면 즉시 반환합니다. –

+0

지금까지이 접근 방식으로 성능상의 이점을 보지 못했습니다. 실행 계획의 스크린 샷을 보여주세요. – montewhizdoh

28

허용 대답은 근시하고 있다는 점에서 문제 약간 느슨하게 :

1) 둘 다 명시 적으로 포함 인덱스 오른쪽 의 좌측 존재 하는지를 언급하지 않거나 양측.

2) 입력 왼쪽 세트의 크기와 입력 오른쪽 세트의 크기를 고려하지 않습니다.
(질문에는 전체적으로 큰 결과, 집합 만 표시됩니다.)

나는 최적화로 인해 상당한 비용 차이가있을 때 대가 "존재" "의"사이의 변환 똑똑 생각 (1), (2), 그렇지 않으면 단지 (힌트로 사용될 수있다 예를 들어, 오른쪽에 검색 가능한 색인의 사용을 권장하기 위해 존재).

두 양식을 내부적으로 조인 형식으로 변환하고 조인 순서를 거꾸로하여 예상 행 수 (왼쪽 및 오른쪽)와 왼쪽, 오른쪽 또는 오른쪽에있는 인덱스 존재 여부에 따라 루프, 해시 또는 병합으로 실행할 수 있습니다. 양측.

+2

이 훌륭한 대답이 더 이상 주목을받지 못하는 이유를 모르겠습니다. 양쪽에 대한 색인/구조를 이해하면 영향을 미칠 수 있습니다. 잘했다. – SheldonH