IT story

SQL Server IN 대 기존 성능

hot-time 2020. 8. 3. 17:36
반응형

SQL Server IN 대 기존 성능


다음 중 어느 것이 더 효율적인지 궁금합니다.

INSQL Server가 결과 집합을 큰 IF으로 바꾼다고 생각하기 때문에 항상 사용에 대해 약간 신중했습니다 . 결과 집합이 크면 성능이 저하 될 수 있습니다. 작은 결과 집합의 경우 어느 쪽이 바람직한 지 잘 모르겠습니다. 큰 결과 집합의 EXISTS경우 더 효율적이지 않습니까?

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

vs.

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

EXISTS 엔진이 적중을 발견하면 조건이 참인 것처럼 종료됩니다.

를 사용하면 IN추가 처리 전에 하위 쿼리에서 모든 결과를 수집합니다.


허용되는 대답은 근시안적이며 그 질문은 약간 느슨합니다.

1) 커버링 지수가 왼쪽, 오른쪽 또는 양쪽에 있는지 명시 적으로 언급하지 마십시오.

2) 입력 왼쪽 세트와 입력 오른쪽 세트의 크기는 고려하지 않습니다.
(질문은 전체적으로 큰 결과 집합을 언급합니다 ).

나는 (1)과 (2)로 인해 상당한 비용 차이가있을 때 옵티마이 저가 "in"과 "exists"사이를 변환하기에 충분히 똑똑하다고 생각합니다. 그렇지 않으면 힌트로 사용될 수 있습니다 (예 : 오른쪽의 탐색 가능한 색인).

두 양식을 내부적으로 결합 양식으로 변환하고 결합 순서를 반대로하고 예상 행 수 (왼쪽 및 오른쪽)와 왼쪽, 오른쪽 또는 양쪽의 색인 존재에 따라 루프, 해시 또는 병합으로 실행할 수 있습니다.


SQL Server 2005 및 2008에서 일부 테스트를 수행했으며 EXISTS와 IN 모두 다른 실제 설명과 동일한 실제 실행 계획으로 돌아옵니다. 최적화 프로그램이 최적입니다. :)

EXISTS, IN 및 JOIN은 쿼리를 올바르게 입력하지 않으면 때때로 다른 결과를 반환 할 수 있습니다. http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210 .aspx


IN을 통해 EXISTS와 함께 갈 것입니다. 아래 링크를 참조하십시오.

SQL Server : JOIN vs IN vs EXISTS-논리적 차이


이 경우 실행 계획은 일반적으로 동일하지만 옵티마이 저가 인덱스의 다른 모든 측면에서 어떻게 영향을 미치는지 알 때까지는 실제로 알 수 없습니다.


따라서 IN은 EXISTS와 같지 않으며 동일한 실행 계획을 생성합니다.

일반적으로 EXISTS는 상관 하위 쿼리에 사용되므로 외부 쿼리와 함께 EXISTS 내부 쿼리에 참여합니다. 외부 쿼리 조인과 내부 쿼리 조인을 해결해야 할 때 결과를 생성하는 단계가 더 많아 져 where 절을 일치시켜 둘 다 조인합니다.

일반적으로 IN은 내부 쿼리와 외부 쿼리를 상관시키지 않고 사용되며 한 단계만으로 해결할 수 있습니다 (최상의 경우).

이걸 고려하세요:

  1. IN을 사용하고 내부 쿼리 결과가 고유 한 값의 수백만 행인 경우 EXISTS 쿼리가 수행되는 경우 (외부 쿼리와 결합 할 올바른 인덱스가 있음) EXISTS보다 SLOWER를 수행합니다.

  2. EXISTS를 사용하고 외부 쿼리와의 조인이 복잡하면 (수행하는 데 더 많은 시간이 걸리고, 적절한 인덱스가 없음) 외부 테이블의 행 수만큼 쿼리 속도가 느려지 며 예상 완료 시간이 며칠이 될 수 있습니다. 주어진 하드웨어에 대해 행 수가 허용되거나 데이터의 카디널리티가 올바른 경우 (예 : 큰 데이터 세트에서 더 적은 DISTINCT 값) IN이 EXISTS보다 빠르게 수행 할 수 있습니다.

  3. 위의 모든 사항은 각 테이블에 상당한 양의 행이있을 때 기록됩니다 (공정하게 말하면 CPU 처리 및 / 또는 캐싱의 램 임계 값을 초과하는 것을 의미합니다).

따라서 대답은 그것입니다. IN 또는 EXISTS 내에 복잡한 쿼리를 작성할 수 있지만 경험상, 고유 한 값이 많은 행이 많을 때는 제한된 고유 값 세트로 EX를 사용하고 EXISTS를 사용해야합니다.

트릭은 스캔 할 행 수를 제한하는 것입니다.

문안 인사,

마리아노


여기에 고도로 공세 된 답변을 포함하여 오해의 소지가 많은 답변이 있습니다 (비록 그들의 작전이 해를 의미한다고 생각하지는 않지만). 짧은 대답은 다음과 같습니다.

(T-) SQL 언어에는 많은 키워드가 있지만 결국 하드웨어에서 실제로 발생하는 유일한 것은 실행 쿼리 계획에서 볼 수있는 작업입니다.

우리가 호출 할 때 우리가 관계형 (수학 이론) 작업 [NOT] IN과는 [NOT] EXISTS반이 (사용하는 경우 안티 조인이다 NOT). 해당 sql-server 조작이 동일한 이름을 갖는 것은 우연의 일치가 아닙니다 . (반) 반 조인 만 언급 IN하거나 EXISTS다른 작업은 없습니다 . 따라서 논리적으로 동등한 INEXISTS선택은 결과를 얻는 유일한 방법 인 (반) 반 조인 실행 작업이 있기 때문에 성능에 영향을 줄 수 있는 방법은 없습니다 .

예를 들면 :

쿼리 1 ( 계획 )

select * from dt where dt.customer in (select c.code from customer c where c.active=0)

쿼리 2 ( 계획 )

select * from dt where exists (select 1 from customer c where c.code=dt.customer and c.active=0)

를 최적화하려면 EXISTS매우 리터럴이어야합니다. 무언가가 있어야하지만 실제로 상관 하위 쿼리에서 반환 된 데이터가 필요하지 않습니다. 부울 조건을 평가하는 중입니다.

그래서:

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

상관 된 하위 쿼리가 RBAR이므로 첫 번째 결과 적중은 조건을 true로 만들고 더 이상 처리되지 않습니다.


내 머리 꼭대기에서 정확하지는 않습니다.이 경우 두 번째가 더 빠를 것이라고 믿습니다.

  1. 첫 번째로, 상관 된 하위 쿼리는 각 행에 대해 하위 쿼리가 실행되도록 할 것입니다.
  2. 두 번째 예에서는 상관되지 않기 때문에 하위 쿼리는 한 번만 실행해야합니다.
  3. 두 번째 예에서 IN일치하는 것을 찾으면 바로 단락됩니다.

참고 URL : https://stackoverflow.com/questions/2065329/sql-server-in-vs-exists-performance

반응형