1

이 쿼리는 원래 ODBC를 통해 외부 데이터베이스에 연결된 MS Access 테이블에 액세스하는 VB6 프로그램에서 왔습니다. 그것은 실행하는 데 약 3:30 걸립니다.연결된 서버를 사용하는 SQL Server 2008에서 느린 쿼리. 나는 무엇을 볼 수 있는가?

이제 더 나은 데이터베이스 시스템으로 마이그레이션하는 방법을 평가할 수있는 SQL Server 2008 Express 상자를 설치했습니다. 그래서 외부 서버 (우리는 DWPROD라고 함)에 연결된 서버를 설치하고 쿼리를 변경 (iif 문을 대소 문자로 변경)하고 실행할 때 12 분 동안 실행하고 여전히 끝내지 않습니다. SQL Server를 처음 사용하기 때문에 오래 걸리는 부분을 보려면 어떻게해야합니까? 이 속도를 높이기위한 제안 사항이 있습니까? 권장되는 리소스가 있으므로이 정보를 자세히 알아볼 수 있습니까? 이것은 우리가 가지고있는 것과 비교되는 간단한 쿼리이므로이 문제를 다시 치게 될 것입니다.

쿼리 : 나는 오래 알고

SELECT [FISCAL_YEAR] AS FISCAL_YEAR, 
[Budgets].[dbo].[Departments].strdepentity AS ENTITY_CODE, 
[Budgets].[dbo].[Departments].depdiv1 AS DIVISION_CODE, 
FINANCIAL_DEPTID AS DEPTID, 
FUND_CODE, 
[CLASS_FLD] AS CLASS_CODE, 
[PROJECT_ID], 
[PROGRAM_CODE], 
[ACCOUNT] AS ACCOUNT_CODE, 
CASE 
    WHEN [ACCOUNT] in ('500020','520000','520220','520240') THEN 2 
    WHEN LEFT([ACCOUNT],1)='5' THEN 1 
    WHEN Left([ACCOUNT],1)='6' THEN 3 
    WHEN Left([ACCOUNT],1)='7' THEN 4 
    WHEN Left([ACCOUNT],1)='8' THEN 5 
    ELSE 0 
    END AS ACCT_GRP_CODE, 
Sum([BUDGET_AMOUNT]) AS GL_BUD_AMT, 
Sum([ENCUMBRANCE_AMOUNT]) AS GL_ENC_AMT, 
Sum([EXPENDITURE_AMOUNT]) AS GL_EXP_AMT, 
CASE 
    WHEN Left([CLASS_FLD],2)='12' THEN 0 
    WHEN Left([CLASS_FLD],3)='113' THEN 3 
    WHEN Left([CLASS_FLD],3)='112' THEN 14 
    WHEN Left([CLASS_FLD],3)='115' THEN 10 
    WHEN Left([CLASS_FLD],3)='116' THEN 13 
    WHEN Left([CLASS_FLD],3)='117' THEN 12 
    WHEN Left([CLASS_FLD],3)='118' THEN 11 
    WHEN Left([CLASS_FLD],2)='13' THEN 2 
    WHEN Left([CLASS_FLD],2)='14' THEN 3 
    WHEN Left([CLASS_FLD],1)='4' THEN 4 
    WHEN Left([CLASS_FLD],1)='6' THEN 6 
    ELSE 9 
    END AS FUND_SOURCE 

FROM [DWPROD]..[DISC].[PS_LEDGER_DETAIL] LEFT JOIN [Budgets].[dbo].[Departments] ON FINANCIAL_DEPTID=[Budgets].[dbo].[Departments].deporg 
WHERE ((([BUDGET_PERIOD])='2010') And (([ACCOUNTING_PERIOD]) Between 1 And 12)) 


GROUP BY 
[FISCAL_YEAR], 
[Budgets].[dbo].[Departments].strdepentity, [Budgets].[dbo].[Departments].depdiv1, 
[FINANCIAL_DEPTID], 
FUND_CODE, 
[CLASS_FLD], 
[PROJECT_ID], 
[PROGRAM_CODE], 
[ACCOUNT], 
CASE 
    WHEN [ACCOUNT] in ('500020','520000','520220','520240') THEN 2 
    WHEN LEFT([ACCOUNT],1)='5' THEN 1 
    WHEN Left([ACCOUNT],1)='6' THEN 3 
    WHEN Left([ACCOUNT],1)='7' THEN 4 
    WHEN Left([ACCOUNT],1)='8' THEN 5 
    ELSE 0 
    END, 
    CASE 
    WHEN Left([CLASS_FLD],2)='12' THEN 0 
    WHEN Left([CLASS_FLD],3)='113' THEN 3 
    WHEN Left([CLASS_FLD],3)='112' THEN 14 
    WHEN Left([CLASS_FLD],3)='115' THEN 10 
    WHEN Left([CLASS_FLD],3)='116' THEN 13 
    WHEN Left([CLASS_FLD],3)='117' THEN 12 
    WHEN Left([CLASS_FLD],3)='118' THEN 11 
    WHEN Left([CLASS_FLD],2)='13' THEN 2 
    WHEN Left([CLASS_FLD],2)='14' THEN 3 
    WHEN Left([CLASS_FLD],1)='4' THEN 4 
    WHEN Left([CLASS_FLD],1)='6' THEN 6 
    ELSE 9 
    END 
HAVING (((FISCAL_YEAR)=2010) 
AND ((FINANCIAL_DEPTID) Between '100' And '999') 
AND ((ACCOUNT) Between '500000' And '899999')) 
ORDER BY [FINANCIAL_DEPTID], [CLASS_FLD], [PROJECT_ID], [ACCOUNT] 

. 보고 주셔서 감사합니다.

+0

연결된 서버 DWPROD은 무엇입니까? 아직도 액세스? – MartW

+0

DWPROD는 연결된 서버입니다. 이 쿼리에는 접근 테이블이 없습니다. dbo.Departments는 SQL Server의 테이블입니다. –

답변

3

내가 다시 썼다 조회 :. 당신이 [DWPROD]에 인덱스가 있더라도

WITH ledger_detail AS (
     SELECT pld.fiscal_year, 
      pld.financial_deptid AS DEPTID, 
      pld.fund_code, 
      pld.class_fld AS CLASS_CODE, 
      pld.project_id, 
      pld.program_code, 
      CASE 
       WHEN pld.account IN ('500020','520000','520220','520240') THEN 2 
       WHEN LEFT(pld.account,1) = '5' THEN 1 
       WHEN LEFT(pld.account,1) = '6' THEN 3 
       WHEN LEFT(pld.account,1) = '7' THEN 4 
       WHEN LEFT(pld.account,1) = '8' THEN 5 
       ELSE 0 
      END AS ACCT_GRP_CODE, 
      pld.budget_amount, 
      pld.encumbrance_amount, 
      pld.expenditure_amount, 
      pld.account AS ACCOUNT_CODE, 
      CASE 
       WHEN LEFT(pld.class_fld, 2) ='12' THEN 0 
       WHEN LEFT(pld.class_fld, 3)='113' THEN 3 
       WHEN LEFT(pld.class_fld, 3)='112' THEN 14 
       WHEN LEFT(pld.class_fld, 3)='115' THEN 10 
       WHEN LEFT(pld.class_fld, 3)='116' THEN 13 
       WHEN LEFT(pld.class_fld, 3)='117' THEN 12 
       WHEN LEFT(pld.class_fld, 3)='118' THEN 11 
       WHEN LEFT(pld.class_fld, 2)='13' THEN 2 
       WHEN LEFT(pld.class_fld, 2)='14' THEN 3 
       WHEN LEFT(pld.class_fld, 1)='4' THEN 4 
       WHEN LEFT(pld.class_fld, 1)='6' THEN 6 
       ELSE 9 
      END AS FUND_SOURCE 
     FROM [DWPROD]..[DISC].[PS_LEDGER_DETAIL] pld 
     WHERE pld.budget_period = '2010' 
     AND pld.accounting_period BETWEEN 1 AND 12 
     AND pld.fiscal_year = 2010 
     AND pld.financial_deptid BETWEEN '100' AND '999' 
     AND pld.account BETWEEN '500000' AND '899999') 
    SELECT x.fiscal_year, 
      y.strdepentity AS ENTITY_CODE, 
      y.depdiv1 AS DIVISION_CODE, 
      x.deptid, 
      x.fund_code, 
      x.class_code, 
      x.project_id, 
      x.program_code, 
      x.acct_grp_code, 
      SUM(x.budget_amount) AS GL_BUD_AMT, 
      SUM(x.encumbrance_amount) AS GL_ENC_AMT, 
      SUM(x.expenditure_amount) AS GL_EXP_AMT, 
      x.account AS ACCOUNT_CODE, 
      x.fund_source 
    FROM ledger_detail x 
LEFT JOIN [Budgets].[dbo].[Departments] y ON y.deporg = x.financial_deptid  
GROUP BY x.fiscal_year, y.strdepentity, y.depdiv1, x.deptid, x.fund_code, x.class_code, x.project_id, x.program_code, x.acct_grp_code 
ORDER BY x.financial_deptid, x.class_fld, x.project_id, x.account 

.. [DISC] [PS_LEDGER_DETAIL]의 accountclass_fld, 함수의 사용 (LEFT) 이 쿼리에 사용할 수 없게 만듭니다.

또한 WHERE 절 대신 HAVING 절에 필터 조건을 포함합니다.

UPDATE : 비 CTE 동등한

SELECT x.fiscal_year, 
      y.strdepentity AS ENTITY_CODE, 
      y.depdiv1 AS DIVISION_CODE, 
      x.deptid, 
      x.fund_code, 
      x.class_code, 
      x.project_id, 
      x.program_code, 
      x.acct_grp_code, 
      SUM(x.budget_amount) AS GL_BUD_AMT, 
      SUM(x.encumbrance_amount) AS GL_ENC_AMT, 
      SUM(x.expenditure_amount) AS GL_EXP_AMT, 
      x.account AS ACCOUNT_CODE, 
      x.fund_source 
    FROM (SELECT pld.fiscal_year, 
        pld.financial_deptid AS DEPTID, 
        pld.fund_code, 
        pld.class_fld AS CLASS_CODE, 
        pld.project_id, 
        pld.program_code, 
        CASE 
        WHEN pld.account IN ('500020','520000','520220','520240') THEN 2 
        WHEN LEFT(pld.account,1) = '5' THEN 1 
        WHEN LEFT(pld.account,1) = '6' THEN 3 
        WHEN LEFT(pld.account,1) = '7' THEN 4 
        WHEN LEFT(pld.account,1) = '8' THEN 5 
        ELSE 0 
        END AS ACCT_GRP_CODE, 
        pld.budget_amount, 
        pld.encumbrance_amount, 
        pld.expenditure_amount, 
        pld.account AS ACCOUNT_CODE, 
        CASE 
        WHEN LEFT(pld.class_fld, 2) ='12' THEN 0 
        WHEN LEFT(pld.class_fld, 3)='113' THEN 3 
        WHEN LEFT(pld.class_fld, 3)='112' THEN 14 
        WHEN LEFT(pld.class_fld, 3)='115' THEN 10 
        WHEN LEFT(pld.class_fld, 3)='116' THEN 13 
        WHEN LEFT(pld.class_fld, 3)='117' THEN 12 
        WHEN LEFT(pld.class_fld, 3)='118' THEN 11 
        WHEN LEFT(pld.class_fld, 2)='13' THEN 2 
        WHEN LEFT(pld.class_fld, 2)='14' THEN 3 
        WHEN LEFT(pld.class_fld, 1)='4' THEN 4 
        WHEN LEFT(pld.class_fld, 1)='6' THEN 6 
        ELSE 9 
        END AS FUND_SOURCE 
      FROM [DWPROD]..[DISC].[PS_LEDGER_DETAIL] pld 
      WHERE pld.budget_period = '2010' 
       AND pld.accounting_period BETWEEN 1 AND 12 
       AND pld.fiscal_year = 2010 
       AND pld.financial_deptid BETWEEN '100' AND '999' 
       AND pld.account BETWEEN '500000' AND '899999') x 
LEFT JOIN [Budgets].[dbo].[Departments] y ON y.deporg = x.financial_deptid  
GROUP BY x.fiscal_year, y.strdepentity, y.depdiv1, x.deptid, x.fund_code, x.class_code, x.project_id, x.program_code, x.acct_grp_code 
ORDER BY x.financial_deptid, x.class_fld, x.project_id, x.account 
+0

내가 이것을 이해하는지 보자. with 절은 기본적으로 메모리에 테이블을 선택하여 만들 수 있습니다. 그렇다면 그것은 참으로 시원합니다. 또한 읽기가 훨씬 쉬워집니다. 이것은 또한 훨씬 더 빠릅니다. 원래 쿼리를 다시 작성하고 5:36이 소요되었으며이 쿼리는 1:08을 차지했습니다. 감사합니다. –

+0

비교 예를 이용해 주셔서 감사합니다. 나는 이것이 내 문제를 해결했기 때문에 대답으로 받아 들였다. 그리고 나는 그것을 대답으로 받아 들인 이후에 내가 그것을위한 것이 분명 할 것이라고 생각했지만 나는 또한 그것을 투표 할 것이다. 도와 주셔서 감사합니다! –

관련 문제