2014-04-25 2 views
2

질문은 SQL 서버에만 적용될 수 있습니다. 나는 같은 쿼리를 작성하는 경우 :WHERE-CASE 절 하위 쿼리 성능

SELECT * FROM IndustryData WHERE Date='20131231' 
AND ReportTypeID = CASE WHEN (fnQuarterDate('20131231')='20131231') THEN 1 
         WHEN (fnQuarterDate('20131231')!='20131231') THEN 4 
         END; 

합니까 함수를 호출 fnQuarterDate (또는 하위 쿼리) 절을 테이블의 각 행에 대해 실행되는 내부 케이스 내?

내가 얻는 경우에 더 나은 것이 얼마나 함수의 (또는 하위 쿼리) 내부 사전에 값 변수 같은 :

DECLARE @X INT 
IF fnQuarterDate('20131231')='20131231' 
SET @X=1 
ELSE 
SET @X=0 
SELECT * FROM IndustryData WHERE Date='20131231' 
AND ReportTypeID = CASE WHEN (@X = 1) THEN 1 
         WHEN (@X = 0) THEN 4 
         END; 

내가 MySQL의에서 IN 내부 하위 쿼리가 있는지 알고 (..) WHERE 절 내에서 각 행에 대해 실행되며 SQL Server에 대해서도 동일하게 검색하려고합니다.

... 약 30K 행

그냥 채워 테이블과의 시간 차이를 발견 :

에 Query1 = 70ms가; 쿼리 2 = 6ms. 나는 그것이 그것을 설명한다고 생각하지만 아직도 그것의 뒤에 실제 사실을 모른다.

또한 UDF 대신 간단한 하위 쿼리가 있으면 어떤 차이가 있습니까?

+1

쿼리에 대한 실제 실행 계획을 얻으려고 했습니까? –

+0

정확히 그 안에 'else null'이 있습니까? fnquarterdate() 값이 같거나 같지 않습니다. 또는 이것은 새롭다 [trinary boolean] (http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx)입니까? 하위 쿼리의 경우 하위 쿼리가 외부 쿼리의 값에 종속 된 값을 갖는 경우 행 별로만 실행됩니다. 예 : 상관 하위 쿼리 –

+0

@MarcB 예, NULL이 없어야합니다. – pxm

답변

1

이론적으로는 성능 향상에 도움이 될 수 있지만 실제로는 스칼라 함수의 기능에 따라 달라질 수 있습니다. 나는이 경우에 (내 추측은 분기의 마지막 날로 날짜를 포맷하는 것입니다) 실제로 무시할 수 있다고 생각합니다.

당신은 제안 해결 방법이 페이지를 읽을 수 있습니다

:

http://connect.microsoft.com/SQLServer/feedback/details/273443/the-scalar-expression-function-would-speed-performance-while-keeping-the-benefits-of-functions#

SQL 서버가 어떤 기능을 사용하여, 모든 행에 각 기능을 실행해야하기 때문에 성능 저하와 같은 커서를 초래한다.

및 해결 방법에

, 나는 스칼라 UDF가에 열을 결합 사용 때이 같은 문제가 있었다

하는 의견이의 성능은 끔찍했다. UDF의 결과가 포함 된 조인 테이블 으로 UDF를 대체하고 조인 절에 사용하면 성능이 더 큰 순서로 나타납니다. MS 팀은 UDF의 을보다 안정적으로 수정해야합니다.

그렇기 때문에 성능이 향상 될 수 있습니다.

귀하의 솔루션은 정확하지만 내가 대신 ELSE 사용하는 SQL의 개선을 고려하는 것이 좋습니다, 그것은 나에게 청소기 같습니다

AND ReportTypeID = CASE WHEN (@X = 1) THEN 1 
        ELSE 4 
        END; 
+0

UDF와 간단한 하위 쿼리의 경우가 동일합니까? – pxm

0

다릅니다. User-Defined Functions을 참조하십시오.

쿼리에 지정된 함수가 실제로 실행되는 횟수는 옵티마이 저가 작성한 실행 계획에 따라 달라질 수 있습니다. 예는 WHERE 절의 부속 조회에 의해 호출되는 함수입니다. 하위 쿼리 및 해당 함수가 실행되는 횟수는 최적화 프로그램에서 선택한 다른 액세스 경로에 따라 달라질 수 있습니다.

0

이러한 접근 방식은 인라인 (in-line) MySQL의 변수 ... 쿼리를 사용 "sqlvars"의 별칭은 문제의 날짜로 @dateBasis를 먼저 준비한 다음 전체 쿼리에 대해 한 번 수행 한 함수 호출을 기반으로하는 두 번째 변수 @qtrReportType을 준비합니다. 그런 다음 크로스 조인 (sqlvars가 단일 행으로 간주되기 때문에 테이블간에 where 절을 사용하지 않음)을 통해이 값을 사용하여 IndustryData 테이블에서 데이터를 가져옵니다.

select 
     ID.* 
    from 
     (select 
       @dateBasis := '20131231', 
       @qtrReportType := case when fnQuarterDate(@dateBasis) = @dateBasis 
           then 1 else 4 end) sqlvars, 
     IndustryData ID 
    where 
      ID.Date = @dateBasis 
     AND ID.ReportTypeID = @qtrReportType