2017-09-22 10 views
0

* 누구나 쿼리를 최적화 할 수 있습니다. 나는이 쿼리를 streamsets라고 불리는 ETL에서 사용하고 있는데, 매우 느린 streamets pipleline을 실행할 때 6 분 동안 70 개의 레코드를 생성한다. 우리는 SSIS 패키지에서이 쿼리를 가져 와서 왼쪽 외부 조인을 사용하여 각 테이블에 합류한다. 이 streamsets 분당이어야 1000 개의 레코드를 가져 있도록 당신이 정말로 당신의 인덱스를 알고있는 테이블과 부속 선택에 가입하면 나는 *SQl 쿼리 최적화

SELECT [FR].[ORDER_ID] 
    , [FR].[FULFILLMENT_REQUEST_ID] 
    , [SR].[SCREENING_RESULT_ID] 
    , [AT].[AG_TASK_ID] 
    , [RCC].[RESULT_CRIM_CASE_ID] 
    , [RCC].[RESULT_CRIM_CHARGE_ID] 
    , [FR].[JURISDICTION_ID] 
    , [COUNTY] = CASE WHEN [FR].[PRODUCT_ID] = 2 THEN [JC].[COUNTY_NAME] ELSE '' END 
    , [STATE] = CASE WHEN [FR].[PRODUCT_ID] = 2 THEN [JC].[STATE_A2_CD] ELSE [JS].[STATE_A2_CD] END 
    , [JT].[JURISDICTION_TYPE_NAME] 
    , [FR].[PRODUCT_ID] 
    , [P].[PRODUCT_NAME] 
    , [FR].[ORGANIZATION_ID] 
    , [O].[ORGANIZATION_NAME] 
    , [SA].[SALARY_RANGE] 
    , [AGE] = YEAR(GETDATE()) - YEAR([FR].[SUBJECT_DOB]) 
    , [FR].[SUBJECT_JOB_COUNTRY] 
    , [FR].[SUBJECT_JOB_STATE] 
    , [FR].[ENTRY_DATE] 
    , [FR].[CREATION_DATE] 
    , [FR].[CLOSED_DATE] 
    , [FR].[EXTERNAL_USER_ID] 
    , [FR].[GENDER_CODE_ID] 
    , [GC].[GENDER_CODE_VALUE] 
    , [AT].[DATA_SOURCE] 
    , [SU].[RESEARCHER_CLASS] 
    , [TT].[TASK_TYPE] 
    , [TT].[TASK_DESCRIPTION] 
    , [RCC].[CHARGE_DESCRIPTION] 
    , [RCC].[DISPOSITION_DESCRIPTION] 
    , [P].[GENERAL_LEDGER_NBR] 
    , [O].[SCHEME_AGENCY_ID] 
    , [RT].[RESULT_TYPE_ID] 
    , [RT].[RESULT_CATEGORY] 
    , [RT].[RESULT_TYPE] 
    , [SU].[USER_ID] 
    ,FR.AG_STATUS_ID 
    , [SCREENING_REFERENCE_ID]=CAST(LEFT([FR].[SCREENING_REFERENCE_ID],250) AS VARCHAR(8000)) 
    ,[P1].POD_NAME 
    , ATH.AG_TASK_HISTORY_ID 
    ,ATH.TASK_STATUS TASK_HISTORY_STATUS 
    , ATH.AG_TASK_DATE TASK_HISTORY_DATE 
    ,[TT].[TASK_TYPE_ID] 
    ,ATH.MODIFIED_BY_SYSTEM_USER_ID 
    ,ATH.CF_SYSTEM_USER_ID 
    ,'' AS [STATUS NOTES] 
    , FR.SCOPE_OF_SEARCH 
    , SR.COMMONNAMFLAG 
    ,CASE WHEN SU.RESEARCHER_CLASS = 'EXTERNAL' THEN SU.[USER_ID] END AS VENDOR 
    , CASE [TT].TASK_TYPE_ID WHEN 14 THEN 'SD IN' WHEN 15 THEN 'MR' WHEN 1 THEN 'ER' END AS [REQUIRED_ACTION] 
    , CASE 
        WHEN [TT].TASK_TYPE_ID = 1 THEN 
            CASE ATH.TASK_STATUS 
            WHEN 'DOCUMENTUPLOADED' THEN 'FMT RECORD ENTRY' 
            WHEN 'ACKNOWLEDGED' THEN 'SEARCHES' 
            WHEN 'AWAITINGHITENTRY' THEN 'AWAITING HIT' 
            WHEN 'DISPUTE' THEN 'AWAITING HIT' 
            WHEN 'DOUBLEENTERRESULTS' THEN 'AWAITING HIT' 
            WHEN 'NEW' THEN 'SEARCHES' 
            WHEN 'SOURCEUNAVAILABLE' THEN 'SEARCHES' 
            WHEN 'UPLOADED' THEN 'SEARCHES' 
            END 
        WHEN [TT].TASK_TYPE_ID = 15 THEN 
            CASE ATH.TASK_STATUS 
            WHEN 'DISPUTE' THEN 'QC' 
            WHEN 'DOCUMENTUPLOADED' THEN 'QC' 
            WHEN 'DOUBLESMARTDATAREVIEW' THEN 'QC' 
            WHEN 'MANUALREVIEW' THEN 'QC' 
            END 
        WHEN [TT].TASK_TYPE_ID = 14 THEN 
            CASE ATH.TASK_STATUS 
            WHEN 'DISPUTE' THEN 'QC' 
            WHEN 'INFONEEDED' THEN 'QC' 
            WHEN 'INFOPROVIDED' THEN 'QC' 
            WHEN 'INFONEEDEDACK' THEN 'QC' 
            WHEN 'NEW' THEN 'QC' 
            WHEN 'SDINFONEEDED' THEN 'CD COMPLIANCE' 
            END 
          END AS [AOM STATUS] 
    , CASE 
            WHEN [TT].TASK_TYPE_ID = 1 AND 
                ATH.TASK_STATUS = 'DOCUMENTUPLOADED' AND 
                ATH.MODIFIED_BY_SYSTEM_USER_ID IS NOT NULL AND 
                ATH.CF_SYSTEM_USER_ID IS NOT NULL THEN 'ER DOCUMENT UPLOADED COMPLETE' 
            WHEN [TT].TASK_TYPE_ID = 14 AND 
                ATH.TASK_STATUS = 'INFONEEDED' THEN 'SD INFO NEEDED INFO NEEDED DATA' 
            WHEN [TT].TASK_TYPE_ID = 1 AND SU.RESEARCHER_CLASS = 'INTERNAL' AND 
             FR.AG_STATUS_ID NOT IN (152) THEN 'ER INTERNAL' 
            WHEN [TT].TASK_TYPE_ID = 1 AND 
                ATH.TASK_STATUS = 'AWAITINGHITENTRY' AND 
                ATH.MODIFIED_BY_SYSTEM_USER_ID IS NOT NULL AND 
                ATH.CF_SYSTEM_USER_ID IS NOT NULL AND 
                ATH.MODIFIED_BY_SYSTEM_USER_ID = ATH.CF_SYSTEM_USER_ID THEN 'ER AWAITING HIT ENTRY DATA' 
            WHEN [TT].TASK_TYPE_ID = 14 THEN 'SD INFO NEEDED DATA' 
            WHEN [TT].TASK_TYPE_ID = 15 AND 
                ATH.TASK_STATUS = 'INFONEEDED' THEN 'MR INFO NEEDED' 
                    END AS AG_OPS_STATUS 
    , FR.EXTERNAL_ORDER_ID 
    , AOT.OTD 
    , drv_pod_name=[P1].POD_NAME 
    , TAT_IN_MIN= Case when TAT_IN_MIN < 0 then 0 else TAT_IN_MIN end 
    , SU2.USER_ID CF_SYS_USER 
    , SU3.USER_ID MODIFIED_SYS_USER 
    , GETDATE() GET_DATE 
    FROM AG_TASK_HISTORY [ATH] LEFT OUTER JOIN 
    (
        (
            (
                (
                    (
                        (
                            (
                                (
                                    (
                                    SELECT [ORDER_ID] ,[FULFILLMENT_REQUEST_ID],[JURISDICTION_ID],[PRODUCT_ID],[ORGANIZATION_ID],[SUBJECT_DOB],[SUBJECT_JOB_COUNTRY],[SUBJECT_JOB_STATE],[ENTRY_DATE],[CREATION_DATE],[CLOSED_DATE],[EXTERNAL_USER_ID],[GENDER_CODE_ID],AG_STATUS_ID,[SCREENING_REFERENCE_ID],SCOPE_OF_SEARCH,EXTERNAL_ORDER_ID,POD_ID,[SALARY_RANGE_ID],[JURISDICTION_TYPE] 
                                    FROM [FULFILLMENT_REQUEST] 
                                    ) FR 
                                    LEFT JOIN 
                                    (
                                        (SELECT [SCREENING_RESULT_ID],[RESULT_TYPE_ID],[FULFILLMENT_REQUEST_ID],COMMONNAMFLAG FROM [SCREENING_RESULT])[SR] 
                                        INNER JOIN [DBO].[RESULT_TYPE] [RT] 
                                        ON [RT].[RESULT_TYPE_ID] = [SR].[RESULT_TYPE_ID] 
                                    ) 
                                    ON [SR].[FULFILLMENT_REQUEST_ID] = [FR].[FULFILLMENT_REQUEST_ID] 
                                ) 
                    INNER JOIN [PRODUCT] [P] 
                    ON [P].[PRODUCT_ID] = [FR].[PRODUCT_ID] 
                    INNER JOIN [ORGANIZATION] [O] 
                    ON [O].[ORGANIZATION_ID] = [FR].[ORGANIZATION_ID] 
                    LEFT JOIN(
                        (SELECT [AG_TASK_ID],[DATA_SOURCE],[TASK_TYPE_ID],[FULFILLMENT_REQUEST_ID],[SYSTEM_USER_ID] FROM [AG_TASK]) [AT] 
                        INNER JOIN [TASK_TYPE] [TT] 
                        ON [TT].[TASK_TYPE_ID] = [AT].[TASK_TYPE_ID] 
                    ) 
                    ON [AT].[FULFILLMENT_REQUEST_ID] = [FR].[FULFILLMENT_REQUEST_ID]) 
                    LEFT OUTER JOIN (
                        (SELECT [RESULT_CRIM_CASE_ID],[SCREENING_RESULT_ID] FROM [RESULT_CRIM_CASE])[RC] 
                        INNER JOIN (SELECT [RESULT_CRIM_CASE_ID],[RESULT_CRIM_CHARGE_ID],[CHARGE_DESCRIPTION],[DISPOSITION_DESCRIPTION] FROM [RESULT_CRIM_CHARGE]) [RCC] 
                        ON [RCC].[RESULT_CRIM_CASE_ID] = [RC].[RESULT_CRIM_CASE_ID] 
                    ) 
                    ON [SR].[SCREENING_RESULT_ID] = [RC].[SCREENING_RESULT_ID] 
                    ) 
                    ) 
                    LEFT JOIN [SYSUSER] [SU] 
                    ON [SU].[SYSTEM_USER_ID] = [AT].[SYSTEM_USER_ID] 
                    LEFT OUTER JOIN [SALARY_RANGE] [SA] 
                    ON [SA].[SALARY_RANGE_ID] = [FR].[SALARY_RANGE_ID] 
                ) 
                LEFT OUTER JOIN [JURISDICTION_TYPE] [JT] 
                ON [JT].[JURISDICTION_TYPE_ID] = [FR].[JURISDICTION_TYPE] 
            ) 
            LEFT OUTER JOIN [GENDER_CODE] [GC] 
            ON [GC].[GENDER_CODE] = [FR].[GENDER_CODE_ID] 
        ) 
        LEFT OUTER JOIN [JURISDICTION_COUNTY] [JC] 
        ON [JC].[JURISDICTION_ID] = [FR].[JURISDICTION_ID] 
        LEFT OUTER JOIN [JURISDICTION_STATE] [JS] 
        ON [JS].[JURISDICTION_ID] = [FR].[JURISDICTION_ID] 
    ) 
    ON [ATH].AG_TASK_ID=[AT].AG_TASK_ID 
    LEFT OUTER JOIN [POD] [P1] ON [FR].POD_ID = [P1].POD_ID 
    LEFT OUTER JOIN(
        SELECT *, (DATEDIFF(MINUTE, [IN_DATE], [IP_DATE]))-(DATEDIFF(WK, [IN_DATE], [IP_DATE]) * (2*24*60))- 
        (CASE WHEN DATENAME(DW, [IN_DATE]) = 'SUNDAY' 
        THEN (24*60) ELSE 0 END) 
        -(CASE WHEN DATENAME(DW, [IP_DATE]) = 'SATURDAY' 
        THEN (24*60) ELSE 0 END) TAT_IN_MIN 
        FROM (
            SELECT FULFILLMENT_REQUEST_ID , MAX([IN_DATE]) [IN_DATE], MAX([IP_DATE]) [IP_DATE] 
            FROM(
                SELECT AG_TASK_HISTORY.FULFILLMENT_REQUEST_ID, 
                CASE WHEN (AG_TASK_HISTORY.TASK_STATUS='INFONEEDED' OR AG_TASK_HISTORY.TASK_STATUS='NEW') AND (SYSUSER.RESEARCHER_CLASS='EXTERNAL' OR SU1.RESEARCHER_CLASS ='EXTERNAL') 
                THEN AG_TASK_HISTORY.AG_TASK_DATE END [IN_DATE], 
                CASE WHEN (AG_TASK_HISTORY.TASK_STATUS='INFOPROVIDED' OR AG_TASK_HISTORY.TASK_STATUS='COMPLETE' OR AG_TASK_HISTORY.TASK_STATUS='DOCUMENTUPLOADED') AND (SYSUSER.RESEARCHER_CLASS='EXTERNAL' OR SU1.RESEARCHER_CLASS ='EXTERNAL') 
                THEN AG_TASK_HISTORY.AG_TASK_DATE END AS [IP_DATE] 
                FROM AG_TASK_HISTORY 
                LEFT JOIN SYSUSER(NOLOCK) ON AG_TASK_HISTORY.CF_SYSTEM_USER_ID = SYSUSER.SYSTEM_USER_ID 
                LEFT JOIN SYSUSER(NOLOCK) SU1 ON AG_TASK_HISTORY.MODIFIED_BY_SYSTEM_USER_ID = SU1.SYSTEM_USER_ID 

                WHERE AG_TASK_DATE >=CAST('01-JAN-'+CAST(YEAR(GETDATE())-3 AS CHAR(4))AS DATETIME) 
            ) A GROUP BY FULFILLMENT_REQUEST_ID 
        )B 
    )AVT 
    ON FR.FULFILLMENT_REQUEST_ID = AVT.FULFILLMENT_REQUEST_ID 
    LEFT OUTER JOIN(
        SELECT *, (DATEDIFF(DAY, [IN_DATE], [IP_DATE]))- 
        (DATEDIFF(WK, [IN_DATE], [IP_DATE]) * (2))- 
        (CASE WHEN DATENAME(DW, [IN_DATE]) = 'SUNDAY' THEN 1 ELSE 0 END) 
        -(CASE WHEN DATENAME(DW, [IP_DATE]) = 'SATURDAY' THEN 1 ELSE 0 END) OTD 
        FROM 
        (
            SELECT FULFILLMENT_REQUEST_ID , MIN(CREATION_DATE) [IN_DATE], GETDATE() [IP_DATE] 
            FROM FULFILLMENT_REQUEST WHERE CLOSED_DATE IS NULL AND AG_STATUS_ID NOT IN (29,134,142,152) 
            GROUP BY FULFILLMENT_REQUEST_ID 
        )B 
    ) AOT 
    ON FR.FULFILLMENT_REQUEST_ID = AOT.FULFILLMENT_REQUEST_ID 
    LEFT OUTER JOIN SYSUSER SU2 
    ON ATH.CF_SYSTEM_USER_ID=SU2.SYSTEM_USER_ID 
    LEFT OUTER JOIN SYSUSER SU3 
    ON ATH.MODIFIED_BY_SYSTEM_USER_ID=SU3.SYSTEM_USER_ID 
    WHERE SU.RESEARCHER_CLASS='EXTERNAL' AND (AVT.TAT_IN_MIN >0 OR AOT.[IP_DATE] IS NULL) 
    AND ATH.AG_Task_Date >=' 2017-07-07 09:02:23.050' 

답변

3

을 최적화 할 필요가있다. 설명을 사용하여 인덱스 사용에 문제점이 있는지 점검하십시오. 쿼리를 최적화 할 수없고 완전히 다시 디자인해야 할 수도 있습니다.

2

쿼리가 거대하고 분석하는 데 오랜 시간이 걸리기 때문에 질문에 명확한 답변을 드릴 수 없습니다. 여기

당신에게 몇 가지 제안은 다음과 같습니다

  1. 가져 오기 실행 계획이 당신에게 어떤 인덱스 제안을 줄 수도
  2. 가에서 모든 열을 제거 누락 (SMSS에 복사하고 CTRL + L 히트)에 대한 SELECT 목록을 선택하고 AG_TASK_HISTORY ....에서 SELECT COUNT (*)를 남겨 둡니다. 여전히 성능이 나쁜지 확인하십시오.
  3. 그런 다음 맨 아래에서 이동하여 조인을 통해 조인을 제거하십시오. 각 제거 후에 성능이 여전히 나쁜지 확인하십시오.
  4. 일부 삭제 작업을 마친 후에는 시간이 많이 걸릴 것이므로 최소한 하나의 병목 현상을 발견했음을 의미합니다.
  5. 는 그런 다음에 대한 적절한 인덱스를 생성하고 2

기타 고려 사항은 (그것이 가능하다면)과 작은 부분으로이 큰 쿼리를 분할 저장 프로 시저를 사용하는 것입니다 단계에서 다시 시도,하지만 난 확신 적절한 인덱스 세트를 사용하면 지금보다 훨씬 나은 성능을 얻을 수 있습니다.