IN을 피해야합니까?


14

일부 SQL Server 개발자들 사이에서는 매우 NOT IN느리다는 믿음이 널리 퍼져 있으며 동일한 결과를 반환하지만 "사악한"키워드를 사용하지 않도록 쿼리를 다시 작성해야합니다. ( ).

그것에 진실이 있습니까?

예를 들어, 사용하여 쿼리를 일으키는 SQL Server의 일부 알려진 버그 (버전?)가되어 NOT IN사용하는 동등한 쿼리보다 더 나쁜 실행 계획을 가지고

  • LEFT JOIN결합 NULL수표
  • (SELECT COUNT(*) ...) = 0에서 WHERE절?

7
이 기사는 매우 정확하지 않습니다. "In"은 "TableOne의 각 행에 대해 동일한 쿼리를 반복해서 실행하지 않습니다". 포스터는 IN/ NOT IN가 항상 중첩 루프로 구현 될 것이라고 생각하는 것 같습니다 . 그리고 나는 무엇 stops SQL Server from creating a ‘plan’을 의미 하는지 전혀 모른다 .
Martin Smith

5
@Heinzi 당신이 연결하는 그 기사는 불에 죽어야하는데, 말도 안되는 소리로 가득합니다. 마찬가지로 : "IN를 교체하려면, 우리는 가입 내부를 사용하여 효과적으로 같은 일이다.." 문제는 그것들이 똑같지 않다는 것입니다. SQL-Server 동작에 대한 모든 것을 분석하기 위해 기본 SQL을 모르는 사람, 즉 조인과 세미 조인의 차이점을 믿지 않습니다.
ypercubeᵀᴹ

답변:


14

나는 그것이 너무 느리다는 것과는 아무런 관련이 없다고 생각합니다. 잠재적으로 부정확 한 내용과 관련이 있습니다. 예를 들어, 개별 고객 또는 B2B 파트너가 주문할 수있는 다음과 같은 데이터가 제공됩니다.

DECLARE @Customers TABLE(CustomerID INT);

INSERT @Customers VALUES(1),(2);

DECLARE @Orders TABLE(OrderID INT, CustomerID INT, CompanyID INT);

INSERT @Orders VALUES(10,1,NULL),(11,NULL,5);

주문한 적이없는 모든 고객을 찾고 싶다고 가정 해 보겠습니다. 데이터가 주어지면 고객 # 2 만 있습니다. 다음은 해당 정보를 찾기 위해 쿼리를 작성하는 세 가지 방법입니다 (다른 방법이 있음).

SELECT [NOT IN] = CustomerID FROM @Customers 
  WHERE CustomerID NOT IN (SELECT CustomerID FROM @Orders);

SELECT [NOT EXISTS] = CustomerID FROM @Customers AS c 
  WHERE NOT EXISTS (SELECT 1 FROM @Orders AS o
  WHERE o.CustomerID = c.CustomerID);

SELECT [EXCEPT] = CustomerID FROM @Customers
EXCEPT SELECT CustomerID FROM @Orders;

결과 :

NOT IN
------
                 -- <-- no results. Is that what you expected?

NOT EXISTS
----------
2

EXCEPT
------
2

이제 몇 가지 성능 문제가 있으며이 블로그 게시물에서 이에 대해 이야기합니다 . 데이터와 인덱스에 따라 NOT EXISTS일반적으로 성능이 우수 NOT IN하며 성능이 더 나빠질 수 있는지 모르겠습니다. 또한 EXCEPT별개의 정렬 작업을 수행 할 수 있으므로 소스에 따라 다른 데이터가 다시 나타날 수 있습니다. 그리고 인기있는 LEFT OUTER JOIN ... WHERE right.column IS NULL패턴은 항상 최악의 수행자입니다.

Martin Smith는 SO에 대한 답변에서 많은 훌륭한 지원 정보를 가지고 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.