2012-10-11 4 views
1

이 쿼리를 최적화하는 데 도움을 줄 수 있습니까? 나는 이것을 최적화 할 방법이 없어졌습니다. 여기서 데이터 검색 시간은 6 분이고 나는 그것을 줄이려고합니다. 당신이 나를 도울 수 있기를 바랍니다.이 쿼리를 최적화하는 데 도움이 필요합니다.

-- Main query 
DECLARE @ProdClass VARCHAR(10) 
,@ModelID VARCHAR(10) 
,@ServiceStartDate DATETIME 
,@ServiceEndDate DATETIME 
,@SvcID VARCHAR(10) 
,@StateID VARCHAR(10) 
,@AreaID VARCHAR(10) 

SET @ProdClass = 'WPS' 
SET @ModelID = 'BM' 
SET @ServiceStartDate = convert(datetime, '10/1/2007') 
SET @ServiceEndDate = CONVERT(DATETIME, '11/1/2007') 
SET @SvcID = '358' 
SET @StateID = 'JB' 
SET @AreaID = '' 

SELECT DISTINCT cus.MCUS_CUSID 
    ,cus.MCUS_ENAME 
    ,mod.MMOD_ENAME 
    ,rou.MROU_SERNO 
    ,svc.MSVC_SVCID AS SVC_NAME 
    ,ar.MARE_ENAME 
    ,dbo.ufn_GetLastXApptDate(rou.MROU_ROUID) AS MROU_APTDT 
    ,rou.MROU_LSVDT 
    ,(
     CASE MROU_FRSVE 
     WHEN 'Y' 
      THEN 'FREE' 
     WHEN 'N' 
      THEN 'NORMAL' 
     END 
    ) AS SERVICE_DUE_TYPE 
FROM dbo.MROU_FIL AS rou 
INNER JOIN dbo.MCUS_FIL AS cus ON rou.MROU_CUSID = cus.MCUS_CUSID 
INNER JOIN dbo.MMOD_FIL AS mod ON rou.MROU_MODID = mod.MMOD_MODID 
INNER JOIN dbo.MSVC_FIL AS svc ON rou.MROU_SVCID = svc.MSVC_SVCID 
INNER JOIN dbo.MADR_FIL AS adr ON cus.MCUS_CUSID = adr.MADR_CUSID 
INNER JOIN dbo.MSTA_FIL AS st ON adr.MADR_STAID = st.MSTA_STAID 
INNER JOIN dbo.MARE_FIL AS ar ON adr.MADR_AREID = ar.MARE_AREID 
INNER JOIN dbo.FAPT_FIL AS apt ON rou.MROU_ROUID = apt.FAPT_ROUID 
WHERE rou.MROU_STAT = 'ACTIVE' 
AND rou.MROU_CUSPF = 'MY' 
AND apt.FAPT_APTTY in ('mf','m1','m2','m3','m4','m5','m6', 'mm') 
AND ((@ProdClass = '') OR (@ProdClass <> '' AND rou.MROU_CLSID = @ProdClass)) 
AND ((@ModelID = '') OR (@ModelID <> '' AND rou.MROU_MODID = @ModelID)) 
AND (
    ((@ServiceStartDate = '') OR (@ServiceStartDate <> '' AND rou.MROU_LSVDT >= @ServiceStartDate)) 
    AND 
    ((@ServiceEndDate = '') OR (@ServiceEndDate <> '' AND rou.MROU_LSVDT <= @ServiceEndDate)) 
) 
AND ((@SvcID = '') OR (@SvcID <> '' AND svc.MSVC_SVCID = @SvcID)) 
AND ((@StateID = '') OR (@StateID <> '' AND adr.MADR_STAID = @StateID)) 
AND ((@AreaID = '') OR (@AreaID <> '' AND adr.MADR_AREID = @AreaID)) 
ORDER BY rou.MROU_LSVDT 


-- function -- 
ALTER FUNCTION [dbo].[ufn_GetLastXApptDate] 
(
@rouid numeric(18,0) 
) 
RETURNS datetime 
AS 
BEGIN 
    DECLARE @ApptDate datetime 

    SELECT @ApptDate = MAX(FAPT_APTDT) 
    FROM dbo.FAPT_FIL 
    WHERE FAPT_ROUID = @rouid 
     AND FAPT_STAT= 'X' 
     AND FAPT_APTTY in ('mf','m1','m2','m3','m4','m5','m6', 'mm') 

    RETURN @ApptDate 

END 
+1

당신은 테이블에 어떤 인덱스가 않습니다 ..하는 당신이 그들이 각 테이블에 대한 쿼리에 나타나는 순서대로 조인 수행하여 키의 모든 컬럼에 인덱스를 만들어보십시오? 없는 경우 시작하십시오. – CatchingMonkey

+0

실제로 많이 있습니다. 나는 어디서부터 시작해야할지 모르겠다. – Musikero31

+0

조인을 수행하는 각 키에는 테이블이 실제로 작지 않은 이상 적어도 인덱스가 있어야합니다. – vstrien

답변

5

SQL Server는 모든 행에 대해 스칼라 함수를 호출해야합니다. 함수의 쿼리를 집합 기반 연산으로 자유롭게 실행하려면 함수를 인라인으로 이동하십시오. 변경 :

,dbo.ufn_GetLastXApptDate(rou.MROU_ROUID) AS MROU_APTDT 

에 :

,(
SELECT MAX(FAPT_APTDT) 
FROM dbo.FAPT_FIL 
WHERE FAPT_ROUID = rou.MROU_ROUID 
     AND FAPT_STAT= 'X' 
     AND FAPT_APTTY in ('mf','m1','m2','m3','m4','m5','m6', 'mm') 
) 

귀하의 쿼리는 매개 변수의 서로 다른 값에 대한 실행 계획 다른 버전의 혜택을 누릴 수있는 검색 쿼리 것 같습니다. 쿼리가 끝날 때마다

option (recompile) 

을 추가하여 강제로 새 쿼리 계획을 세울 수 있습니다.

+0

함수에서이 코드를 유지 보수하려면 rouid, LastXApptDate를 리턴하는 테이블 함수로 변환하십시오. 이 답변과 동일한 성능 향상을 얻지는 못하지만 코드를 재사용 할 수는 있습니다. – JeffO

+0

@JeffO : [인라인 테이블 값 함수] (http://msdn.microsoft.com/en-us/library/ms189294 (v = sql.105) .aspx)는 코드를 인라인하는 것만 큼 효율적입니다. – Andomar

+0

알았습니다. 정말 고마워! 나는 함수 호출이 항상 쿼리의 성능에 영향을 준다는 것을 몰랐다. – Musikero31

관련 문제