2014-06-10 86 views
0

系統有一個存儲過程,有7個選擇並使用UNION將其聯合起來。我已優化,但查詢仍然很慢。存儲過程:查詢優化

有沒有辦法更快地做到這一點?

我試過用CASE更快,但仍然很慢。執行時間是一分鐘。

根據下面的查詢,我應該創建哪些索引?

CODE

ALTER PROCEDURE [dbo].[USP_DEN_S_CONTROLE_DIARIO] 
(
    @CLI_N_CODIGO NUMERIC(18), 
    @DATA_CONSULTA DATETIME 
) 
AS 

DECLARE @DATA AS DATE = DBO.FUN_DEN_DATA_SEM_HORA(@DATA_CONSULTA) 

SELECT DISTINCT 
    PAC.PAC_N_CODIGO, 
    PAC.PAC_C_NOME, 
    PAC.PAC_C_MATRICULA, 
    PAC.PAC_D_ULTIMA_VISITA, 
    CASE ODO.ODO_PTR_N_CODIGO 
     WHEN 2 THEN 'S' 
     WHEN 1 THEN 'N' 
     ELSE 'N' 
    END AS ORCAMENTO, 
    CTR.CTR_C_CODINTELIGENTE, 
    CTR.CTR_N_VALOR_RECEBIDO, 
    (SELECT SUM(VIN_N_VALOR) FROM DEN_VIN_VINCULO_TRATAMENTO WHERE VIN_OXD_ODO_N_CODIGO = ODO_N_CODIGO) AS VALOR_ORC, 

    CASE WHEN CTR.CTR_DET_N_CODIGO IS NULL THEN 
     (SELECT DET_C_NOME FROM DEN_DET_DENTISTA WHERE DET_N_CODIGO = PAC.PAC_DET_N_CODIGO AND DET_CLI_N_CODIGO = @CLI_N_CODIGO) 
    ELSE  
     (SELECT DET_C_NOME FROM DEN_DET_DENTISTA WHERE DET_N_CODIGO = CTR.CTR_DET_N_CODIGO AND DET_CLI_N_CODIGO = @CLI_N_CODIGO) 
    END AS DENTISTA, 

    CASE WHEN ODO.ODO_PTR_N_CODIGO IS NULL AND CTR.CTR_N_VALOR_RECEBIDO IS NULL 
    THEN 
     CASE WHEN 
     (
     SELECT COUNT(*) FROM 
      DEN_VIN_VINCULO_TRATAMENTO INNER JOIN DEN_ODO_ODONTOGRAMA ON VIN_OXD_ODO_N_CODIGO = ODO_N_CODIGO 
     WHERE 
      ODO_PAC_N_CODIGO = PAC_N_CODIGO AND ODO_B_ATIVO = 1 
     AND 
      (
       DBO.FUN_DEN_DATA_SEM_HORA(ODO_D_DATA_CADASTRO) = @DATA 
      OR 
       DBO.FUN_DEN_DATA_SEM_HORA(VIN_D_DATA_REALIZADO) = @DATA 
      OR 
       DBO.FUN_DEN_DATA_SEM_HORA(VIN_D_DATA_CADASTRO) = @DATA 
      ) 
     ) = 0 
     THEN 
      '1' 
     ELSE 
      '0' 
     END 
    ELSE 
     '0' 
    END AS SEM_AGENDAMENTO 
FROM 
    DEN_PAC_PACIENTE PAC 
LEFT JOIN 
    DEN_CTR_CONTA_RECEBER CTR ON (CTR.CTR_PAC_N_CODIGO = PAC.PAC_N_CODIGO) 
           AND CTR.CTR_B_ATIVO = 1 
           AND (DBO.FUN_DEN_DATA_SEM_HORA(CTR.CTR_D_DATA_RECEBIMENTO) = @DATA) 
LEFT JOIN 
    DEN_ODO_ODONTOGRAMA ODO ON (ODO.ODO_N_CODIGO = CTR.CTR_ODO_N_CODIGO 
           OR 
           (ODO.ODO_PAC_N_CODIGO = PAC.PAC_N_CODIGO 
           AND 
           (ODO_B_APROVADO = 0 OR ODO_B_APROVADO IS NULL)) 
           ) 
          AND DBO.FUN_DEN_DATA_SEM_HORA(ODO.ODO_D_DATA_CADASTRO) = @DATA 
WHERE 
    PAC.PAC_B_ATIVO = 1 
    AND DBO.FUN_DEN_DATA_SEM_HORA(PAC.PAC_D_ULTIMA_VISITA) = @DATA 
    AND PAC.PAC_CLI_N_CODIGO = @CLI_N_CODIGO 
ORDER BY 
    PAC.PAC_D_ULTIMA_VISITA 
+1

'我已經優化了,但查詢仍然很慢。'你怎麼知道要優化什麼?你看過執行計劃嗎?你在桌上有適當的索引嗎? –

+0

我重新進行了查詢。我是一名Web開發人員,對數據庫知之甚少。我想要一個關於查詢的意見。 – guinatal

+0

難以閱讀......您可以使用連接將所選字段內的子查詢移動到FROM子句中嗎? –

回答

0

您可以創建一個#temp表和所有記錄插入到它。我假設你使用Union以後,你所有的select查詢必須返回相同數據類型的coulmns。將記錄插入臨時表時不要使用聯合。最後,從臨時表中選擇*。

通過單獨的選擇查詢將記錄插入臨時表將比7個聯合選擇查詢更快。