2010-12-07 3 views
0

다음 두 쿼리는 동일한 결과를 얻지 만 그룹을 사용하는 쿼리는 더 빠르게 실행됩니다. 가능한 경우 최적화 된 쿼리가 그룹을 사용하는 것을 선호합니까? 아니면 어떤 특별한 경우가 발생했을 가능성이 더 큽니까?왜 sql 쿼리를 통해 그룹을 훨씬 빠르게 만들 수 있습니까?

빠른 쿼리 (나에게 덜 직관적) :

SELECT  A.Advertiser 
FROM   (SELECT  TOP (100) PERCENT Advertiser, [Final Status] 
         FROM   dbo.Rehenas_View_2 
         GROUP BY [Final Status], Advertiser 
         HAVING  ([Final Status] IS NULL)) AS A INNER JOIN 
          (SELECT  TOP (100) PERCENT Advertiser, [Final Status] 
          FROM   dbo.Rehenas_View_2 AS Rehenas_View_2_1 
          GROUP BY [Final Status], Advertiser 
          HAVING  ([Final Status] = N'final')) AS B ON A.Advertiser = B.Advertiser 
GROUP BY A.Advertiser 

느린 쿼리를 두 쿼리가 보인다

SELECT  A.Advertiser 
FROM   (SELECT  TOP (100) PERCENT Advertiser, [Final Status] 
         FROM   dbo.Rehenas_View_2 
         WHERE  ([Final Status] IS NULL)) AS A INNER JOIN 
          (SELECT  TOP (100) PERCENT Advertiser, [Final Status] 
          FROM   dbo.Rehenas_View_2 AS Rehenas_View_2_1 
          WHERE  ([Final Status] = N'final')) AS B ON A.Advertiser = B.Advertiser 
GROUP BY A.Advertiser 
+0

둘 다 EXPLAIN PLAN을 실행하면 힌트가 제공 될 수 있습니다. – duffymo

+1

성능은 이것이 어느 db인지에 따라 다릅니다. 확실하게 MSSQL 인 것처럼 보이지만 명시 적으로 태그를 지정해야합니다. –

+1

각 쿼리를 몇 번이나 시도 했습니까? 하나는 캐시 될 수 있습니다. 테이블에 어떤 지표가 있습니까? 그룹에 대한 해시 검색을 수행 할 수 있습니다. 중복 된 광고주/최종 상태 쌍이 많이 있습니까? 나는 필터가 중복이 제거 된 후에 발생한다고 생각하는데, 반면 인덱스와 쿼리 계획에 따라 전체 테이블 스캔을 수행한다고 생각합니다. – vol7ron

답변

0

(나는 속도 차이를 발견 할 때까지 위를 단순화하기 위해 노력했다) 훨씬 더 복잡해. 그들은 이것과 같은 결과를주지 않습니까?

SELECT Advertiser 
FROM   dbo.Rehenas_View_2 
WHERE [Final Status] IS NULL 

UNION 

SELECT Advertiser 
FROM dbo.Rehenas_View_2 
WHERE [Final Status] = N'final' 

또한 훨씬 빨라야합니다.

물론 뷰에서 선택할 때마다 쿼리 자체를 볼 수 없으므로 sql 뷰를 살펴 봐야합니다. 하위 뷰를 사용하는 것과 거의 같지만 구체화 된 뷰인 경우는 예외입니다.

+1

내가 알기에 충분한 세부 정보를 제공하지는 못했지만,보기의 모든 행이 [최종 상태]에 NULL 또는 '최종'이 있고 질문에 답변하려고하는 경우입니다. 어떤 광고주가 부분적으로 마무리 "- 즉 일부 행은 첫 번째 조건을 충족하고 일부 행은 후자를 충족 .... SQL은 내 강한 소송이 아니며 조언을 주려고 노력합니다. –

+0

@Gabriel, 샘플 데이터를 게시하는 것이 좋습니다. 이상적으로는 작은 CREATE TABLE 문과 INSERT 문 세트와 함께 소스 데이터로 테이블을 생성 한 다음 기대 한 실제 결과 목록을 작성하는 것이 이상적입니다. –

0

두 쿼리에서 가장 바깥 쪽 그룹을 제거하면 반환되는 행의 수에 차이가 있습니까? 설명 할 수 있습니다.

1

귀하의 의견에 따르면 귀하는 NULL 및 최종 상태가 모두있는 광고주를 원합니다.

이렇게하면 원하는 결과가 렌더링됩니다. 일반적으로 DISTINCT는 "중복을 얻고 있습니다 ... 확실하지 않은 이유"라고 말하며 대개 팬 트랩을 숨 깁니다. 이 경우 광고주별로 '최종'및 NULL 행의 데카르트 곱을 가질 수 있습니다.

SELECT DISTINCT A.Advertiser 
FROM dbo.Rehenas_View_2 AS A, 
     dbo.Rehenas_View_2 AS B 
WHERE A.[Final Status] IS NULL 
    AND B.[Final Status] = N'final' 
    AND A.Advertiser = B.Advertiser 

INNER는 2 집계의 가입 :

SELECT Advertiser FROM 
( SELECT Advertiser, COUNT(1) AS StatusCount 
    FROM dbo.Rehenas_View_2 WHERE [Final Status] IS NULL 
    GROUP BY Advertiser 
    HAVING StatusCount > 0) AS N, 
(
    SELECT Advertiser, COUNT(1) AS StatusCount 
    FROM dbo.Rehenas_View_2 WHERE [Final Status] = N'final' 
    GROUP BY Advertiser 
    HAVING StatusCount > 0) AS F 
WHERE N.Advertiser = F.Advertiser 

또 다른 아이디어는 CASE를 사용하고 /이

SELECT Advertiser FROM 
( SELECT Advertiser, 
     SUM(CASE WHEN [Final Status] IS NULL THEN 1 ELSE 0 END) AS NullCount, 
     SUM(CASE WHEN [Final Status] = N'final' THEN 1 ELSE 0 END) AS FinalCount 
    FROM dbo.Rehenas_View_2 WHERE [Final Status] IS NULL 
    GROUP BY Advertiser 
    HAVING NullCount > 0 AND FinalCount > 0) 

내가 필요는 없습니다함으로써 하나의 그룹으로 NULL 카운트 결승전입니다 이 구문을 테스트하는 환경.

관련 문제