提高SQL查询的性能

时间:2018-09-11 01:32:17

标签: sql sql-server

我编写了一个涉及INNER JOINLEFT OUTER JOINUNIONSUBQUERY的SQL查询,这需要很长时间才能执行。我的SQL技能不是很好,如果有人可以帮助我如何优化以下查询以使其更快,我将不胜感激。

SELECT [l].[ACCOUNT_ID]
      ,[l].[CONTACT_ID]
      ,[l].[JOB_ROLE]
      ,[l].[JOB_FUNCTION]
      ,[l].[STATE]
      ,[l].[COUNTRY]
      ,[acc].[EMPLOYEE_COUNT] AS [EmpSize]
      ,[r].[CALL_DATE]
      , CONVERT(varchar(20), [r].[DURATION]) AS [COMMENTS]
      ,[r].[LOCATIONS]
FROM [dbo].[tbl_V_S_CONTACT] AS [l]
INNER JOIN [dbo].[CALL_DETAILS_RECORDS_CLEAN] AS [r] ON [l].[CONTACT_ID] = [r].[CON_PER_ID]
LEFT OUTER JOIN [dbo].[tbl_V_S_ACCOUNT] AS [acc] ON [l].[ACCOUNT_ID] = [acc].[ACCT_ID]
WHERE [l].[CONTACT_ID] IN (SELECT [b].[CON_PER_ID]
                           FROM [dbo].[S_SRC] AS [a]
                           INNER JOIN [dbo].[S_CAMP_CON] AS [b] ON [a].[ROW_ID] = [b].[SRC_ID] 
                           WHERE [a].[STATUS_CD] = 'Launched'
                           AND [a].[PROG_END_DT] > CONVERT(varchar, GETDATE(), 101))
AND [l].[COUNTRY] IN ('United States', 'Canada')
AND [r].[CALL_DATE] >= '01-01-2017' AND [r].[CALL_DATE] <= '2018-03-20'
UNION
SELECT [l].[ACCOUNT_ID]
      ,[l].[CONTACT_ID]
      ,[l].[JOB_ROLE]
      ,[l].[JOB_FUNCTION]
      ,[l].[STATE]
      ,[l].[COUNTRY]
      ,[acc].[EMPLOYEE_COUNT] AS [EmpSize]
      ,[act].[TODO_PLAN_START_DT] AS [CALL_DATE]
      ,[act].[COMMENTS]
      ,'Philadelphia' AS [LOCATIONS]
FROM [dbo.tbl_V_S_CONTACT] AS [l]
INNER JOIN [SiebProd].[dbo].[S_EVT_ACT] AS [act] ON [l].[CONTACT_ID] = [act].[PR_CON_ID]
LEFT OUTER JOIN [dbo].[tbl_V_S_ACCOUNT] AS [acc] ON [l].[ACCOUNT_ID] = [acc].[ACCT_ID]
WHERE [l].[CONTACT_ID] IN (SELECT [b].[CON_PER_ID]
                           FROM [dbo].[S_SRC] AS [a]
                           INNER JOIN [dbo].[S_CAMP_CON] AS [b] ON [a].[ROW_ID] = [b].[SRC_ID]
                           WHERE [a].[STATUS_CD] = 'Launched'
                           AND [a].[PROG_END_DT] > CONVERT(varchar, GETDATE(), 101))
AND [l].[COUNTRY] IN ('United States', 'Canada')
AND [act].[CEM_PLAN_START_DT] <= CONVERT(varchar, GETDATE(), 101)
AND [act].[TODO_CD] = 'Call Disposition'
AND [act].[COMMENTS] IS NOT NULL
AND [act.REF_NUM] IS NOT NULL
AND [X_CALL_DISPOSITION] IS NOT NULL
AND [act].[X_DISPOSITION_FLG] = 'Y'

1 个答案:

答案 0 :(得分:1)

有许多步骤可以改善您的查询。

首先纠正一个问题,

我的代码未经测试,但肯定会提高性能。 了解想法并修复错误

-- Put all require columns of [dbo].[tbl_V_S_CONTACT] AS [l]
Create table #Contact(ACCOUNT_ID,CONTACT_ID,JOB_ROLE,JOB_FUNCTION,STATE,COUNTRY)

INSERT INTO #Contact
SELECT [l].[ACCOUNT_ID]
      ,[l].[CONTACT_ID]
      ,[l].[JOB_ROLE]
      ,[l].[JOB_FUNCTION]
      ,[l].[STATE]
      ,[l].[COUNTRY]
      ,[acc].[EMPLOYEE_COUNT] AS [EmpSize]        
FROM [dbo].[tbl_V_S_CONTACT] AS [l]
LEFT OUTER JOIN [dbo].[tbl_V_S_ACCOUNT] AS [acc] ON [l].[ACCOUNT_ID] = [acc].[ACCT_ID]
WHERE [l].[CONTACT_ID] IN (SELECT [b].[CON_PER_ID]
                           FROM [dbo].[S_SRC] AS [a]
                           INNER JOIN [dbo].[S_CAMP_CON] AS [b] ON [a].[ROW_ID] = [b].[SRC_ID] 
                           WHERE [a].[STATUS_CD] = 'Launched'
                           AND [a].[PROG_END_DT] > CONVERT(varchar, GETDATE(), 101))
AND [l].[COUNTRY] IN ('United States', 'Canada')




SELECT [l].[ACCOUNT_ID]
      ,[l].[CONTACT_ID]
      ,[l].[JOB_ROLE]
      ,[l].[JOB_FUNCTION]
      ,[l].[STATE]
      ,[l].[COUNTRY]
      ,[acc].[EMPLOYEE_COUNT] AS [EmpSize]
      ,[r].[CALL_DATE]
      , CONVERT(varchar(20), [r].[DURATION]) AS [COMMENTS]
      ,[r].[LOCATIONS]
FROM #Contact AS [l]
INNER JOIN [dbo].[CALL_DETAILS_RECORDS_CLEAN] AS [r] ON [l].[CONTACT_ID] = [r].[CON_PER_ID]

WHERE [r].[CALL_DATE] >= '01-01-2017' AND [r].[CALL_DATE] <= '2018-03-20'

UNION -- use UNION ALL if possible

SELECT [l].[ACCOUNT_ID]
      ,[l].[CONTACT_ID]
      ,[l].[JOB_ROLE]
      ,[l].[JOB_FUNCTION]
      ,[l].[STATE]
      ,[l].[COUNTRY]
      ,[acc].[EMPLOYEE_COUNT] AS [EmpSize]
      ,[act].[TODO_PLAN_START_DT] AS [CALL_DATE]
      ,[act].[COMMENTS]
      ,'Philadelphia' AS [LOCATIONS]
FROM #Contact AS [l]
INNER JOIN [SiebProd].[dbo].[S_EVT_ACT] AS [act] ON [l].[CONTACT_ID] = [act].[PR_CON_ID]

WHERE [act].[CEM_PLAN_START_DT] <= CONVERT(varchar, GETDATE(), 101)
AND [act].[TODO_CD] = 'Call Disposition'
AND [act].[COMMENTS] IS NOT NULL
AND [act.REF_NUM] IS NOT NULL
AND [X_CALL_DISPOSITION] IS NOT NULL
AND [act].[X_DISPOSITION_FLG] = 'Y'