2011-02-17 5 views
1

여기 내가 처리하고있는 상황이 있습니다.T-SQL : 조인에 대한 내부 쿼리를 사용할 때의 성능

SELECT c.CustID, a.City, a.Country FROM Customers AS c 
    LEFT OUTER JOIN Addresses AS a ON c.CustID = a.CustID 
    WHERE c.LastName = 'Jones' 

그래서 내가 어떤 주소 항목없이 성 존스 모든 고객, 심지어 사람을 보여주고 싶은, 그리고 쇼는 그들을 위해 주소를 관련 : 내가 가진 원래의 쿼리이었다. 그러나 주소에 WHERE 절을 넣고 모든 고객을 표시하려면 어떻게해야합니까? 예를 들면 다음과 같습니다.

SELECT c.CustID, a.City, a.Country FROM Customers AS c 
    LEFT OUTER JOIN Addresses AS a ON c.CustID = a.CustID 
    WHERE c.LastName = 'Jones' AND a.Country = 'United States' 

나는 미국에 거주하지 않은 고객을 잃게됩니다. 그러나 그것은 내가 원하는 것이 아닙니다. 모두 성이 'Jones'인 고객은 미국에 거주하지 않는 주소 만 누락하면 주소 만 누락됩니다. 이것은 내가 해낸 솔루션 :이 경우

SELECT c.CustID, a.City, a.Country FROM Customers AS c 
    LEFT OUTER JOIN 
     (SELECT City, Country FROM Addresses 
     WHERE Country = 'United States') AS a 
    ON c.CustID = a.CustID 
    WHERE c.LastName = 'Jones' 

, 난 여전히 성 존스와 함께 모든 고객을 얻을 수 있지만, 내가 원하는 무엇 미국, 외부에있는 주소를 볼 수 없습니다.

여기 내 문제입니다 : 세 번째 쿼리에서, 나는 그 SQL 서버를 가정하고있어 많은 비 존스 주소가 불필요하게 인출 된 의미하는가 고객 테이블과 조인 않는 다음 모든 미국 주소를 가져와. 두 번째 쿼리에서 SQL Server가 처음에 LastName = 'Jones' 인 주소를 가져 오는 지 궁금합니다. 쿼리를 훨씬 빨리 수행 할 수 있다고 생각합니다. 3 번째 쿼리보다 성능이 향상 되었습니까? 또한, 당신이주는 대답이 무엇이든간에, 내부 조인을 처리 할 때 어떤 차이가 있다고 말할 수 있다면 (있는 경우) 그 것이 좋을 것입니다.

감사합니다. 에 관해서는

SELECT 
    c.CustID, 
    a.City, 
    a.Country 

FROM Customers AS c 

LEFT JOIN Addresses AS a ON c.CustID = a.CustID AND a.Country = 'United States' 

WHERE c.LastName = 'Jones' 

:

답변

3

당신은 단순히 당신의 left join에 추가적인 제약 조건을 추가 할 수 있습니다 (여기에 단어 outer 모든 LEFTRIGHT 조인 자동으로 OUTER, 그리고 모든 자격이 자동 있습니다 INNER에 가입, 중복) 귀하의 질문에 관한 성능, 오직 대답은 두 쿼리를 실행하고 실행 계획을 비교하는 것입니다. 즉, 순수하게 조인 기반 구문이 훨씬 간단 해지고 더 간단하고 빠른 실행 계획을 수립 할 수 있습니다.

1

쿼리의 간단한 형태가 될 것이다 : 그것은 당신보다 더 나은 쿼리 될 경우

SELECT c.CustID, a.City, a.Country 
FROM Customers AS c  
LEFT OUTER JOIN Addresses AS a 
    ON c.CustID = a.CustID AND a.Country = 'United States'  
WHERE c.LastName = 'Jones' 

가 나는 실행 계획을보고 제안을 참조하십시오.

쿼리 2가 작동하지 않는 이유는 where 절에 조건을 넣어 효과적으로 내부 이진으로 만들었 기 때문입니다.

3

조인 조건의 country 부분에 대한 테스트를 만듭니다.

SELECT c.CustID, a.City, a.Country 
    FROM Customers AS c 
     LEFT OUTER JOIN Addresses AS a 
      ON c.CustID = a.CustID 
       AND a.Country = 'United States' 
    WHERE c.LastName = 'Jones' 
1
SELECT c.CustID, a.City, a.Country 
    FROM Customers AS c LEFT OUTER JOIN Addresses AS a ON c.CustID = a.CustID 
WHERE c.LastName = 'Jones' 
    AND (a.Country = 'United States' OR a.Country IS NULL) 
+0

코드 스니 펫은 가능한 솔루션을 보여주기위한 방법이지만 모든 사람에게 항상 명확한 것은 아닙니다. 솔루션이 무엇인지, 코드가이를 달성하기 위해 어떻게 작동하는지에 대한 설명을 항상 제공하십시오. – XenoRo

0

성능을 조사하는 동안, 당신이 적용 운영자 시도 할 수 있습니다 : 오른쪽 표가 큰 경우, 때때로

SELECT c.CustID, a.City, a.Country 
FROM Customers AS c 
    OUTER APPLY 
    (
     SELECT City, Country 
     FROM Addresses 
     WHERE c.CustID = a.CustID 
      AND a.Country = 'United States' 
    ) AS a 
WHERE c.LastName = 'Jones' 

을하고, 최적화 생각 레코드의 5 % 이상이 반환 될 경우 테이블 조인과 외부 조인을 통한 해시 일치를 얻게됩니다. 그러나 인덱스 찾기 및 중첩 루프가 더 빠릅니다. 필자는 이러한 상황에서 APPLY 연산자를 사용하여 성능을 크게 향상 시켰습니다.

이것이 귀하의 경우에 어떻게 나타날지 모르지만 실행 시간과 계획을 비교해 볼 가치가 있습니다.

관련 문제