2016-12-10 13 views
0

我有一个存储过程,获取60个记录,并花费7-8秒,提示改善存储过程。如何使用group by子句优化包含多个子查询的存储过程?

ALTER PROCEDURE [dbo].[Exat_ProductionLog] 
    @Condition varchar(max) = '' 
AS 
BEGIN 
    EXEC ('declare @startedstatus uniqueidentifier = (select [dbo].[GetMasterSatusByName](''WIP'')) 
    DECLARE @Clarification uniqueidentifier = (select [dbo].[GetMasterSatusByName](''OnHold'')) 
    DECLARE @Completed uniqueidentifier = (select [dbo].[GetMasterSatusByName](''Completed'')) 

    SELECT A.*,Total = A.NoofAccounts 
    FROM 
     (SELECT DISTINCT 
      J.ReceivedOn ReceivedOn, 
      CONVERT(varchar(10), J.ReceivedOn, 20) ReceivedDate, 
      (SELECT TOP 1 
        Convert(varchar(10), AssignedDate, 20) 
       FROM AssignedCase 
       WHERE CaseID = AC.CaseID 
       ORDER BY AssignedDate DESC) AssignedDate, 
      UF.Name Facility, UT.Name [Type], 
      C.CaseNumber Batch, C.ACHA ACHA, J.Noofaccounts, 
      [BatchStartdate] = Convert(varchar(10), (select top 1 StatusOnUTC from log_CaseStatus where CaseID = C.CaseID and [email protected] order by StatusOnUTC asc),20), 
      [AccountProcessed]=(select COUNT(*) from Account ACC inner join log_AccountStatus LA on LA.AccountID = ACC.AccountId where ACC.CaseId = C.CaseID and [email protected]), 
      [ClarificationLog] =(select dbo.[Exat_GetClarificationCount](C.CaseID)), 
      [Status] = (select Name from [MasterStatus] where StatusId = (select [dbo].[GetStatusIdByCaseID](C.CaseID))), 
      [Reviewer] =(select SUBSTRING((SELECT ('','' + DisplayName) from um_user where UserID in 
       (select UserID from AssignedCase where CaseID = C.CaseID and [Type] in(''DC'',''Demo'',''Charges''))FOR XML PATH('''')), 2, 1000)), 
       [Auditor] =(select SUBSTRING((SELECT ('','' + DisplayName) from um_user where UserID in 
       (select ValidatedBy from Account where Validated = 1 and CaseID = C.CaseID)FOR XML PATH('''')), 2, 1000)), 
       [AuditCount] = (select Count(*) from Account where CaseID = C.CaseID), 
       [Errors] = (select Count(*) from log_AccountError LA inner join Account ACO on ACO.AccountID = LA.AccountID where ACO.CaseID = C.CaseID) 

    from [Job] J inner join [Case] C on J.JobID = C.JobID 
    inner join log_casestatus lcs on lcs.caseid=c.caseid 
    inner join [Account] A on C.CaseID = A.CaseID inner join [AssignedCase] AC on AC.CaseID = C.CaseID 
    inner join um_Facility UF on UF.FacilityID = J.FacilityID 
    inner join um_Type UT on UT.TypeID = J.TypeID 
    inner join log_AccountStatus LA on LA.AccountID = A.AccountID)A where 1=1 '[email protected]+'') 


End 

提高所述SP性能的任何线索?

在此先感谢。

+0

你是否能够添加主查询的执行计划 – pacreely

+0

在执行计划主选择A. *,......花了99%的成本。所有其他需要1%。 –

+0

查看性能改进之前我建议您尝试停止使用EXEC并将其转换为sp_ExecuteSQL。 EXEC很容易发生SQL注入。 – pacreely

回答

0

我已经通过代码替换您的存储过程不可重复,并且已经使用过您的表只连接一次。试试这样:

ALTER PROCEDURE [dbo].[Exat_ProductionLog] 
    @Condition varchar(max) = '' 
AS 
BEGIN 
    EXEC ('declare @startedstatus uniqueidentifier = (select [dbo].[GetMasterSatusByName](''WIP'')) 

    DECLARE @Clarification uniqueidentifier = (select [dbo].[GetMasterSatusByName](''OnHold'')) 
    DECLARE @Completed uniqueidentifier = (select [dbo].[GetMasterSatusByName](''Completed'')) 

    SELECT A.*,Total = A.NoofAccounts 
    FROM 
     (SELECT DISTINCT 
      J.ReceivedOn, 
      CONVERT(varchar(10), J.ReceivedOn, 20) ReceivedDate, 
      ASSC.AssignedDate, 
      UF.Name Facility, UT.Name [Type], 
      C.CaseNumber Batch, C.ACHA , J.Noofaccounts , 
      BSD.BatchStartdate, 
      LSS.AccountProcessed, 
      [ClarificationLog] =(select count(distinct LAS.AccountID) from log_AccountStatus LAS where A.AccountID = LAS.AccountID and [email protected]) ,     
      [Status] = (select Name from [MasterStatus] where StatusId = (select [dbo].[GetStatusIdByCaseID](C.CaseID))), 
      [Reviewer] = (select SUBSTRING((SELECT ('','' + DisplayName) 
          from um_user where UserID in 
       (select UserID from AssignedCase where CaseID = C.CaseID and [Type] in(''DC'',''Demo'',''Charges''))FOR XML PATH('''')), 2, 1000)), 

      [Auditor] =(select SUBSTRING((SELECT ('','' + DisplayName) from um_user where UserID in 
       (select ValidatedBy from Account where Validated = 1 and CaseID = C.CaseID)FOR XML PATH('''')), 2, 1000)), 

      [AuditCount] = (select Count(*) from Account where CaseID = C.CaseID), 

      ERR.[Errors] 

      from [Job] J 
      inner join [Case] C on J.JobID = C.JobID 
      inner join [Account] A on C.CaseID = A.CaseID 
      inner join um_Facility UF on UF.FacilityID = J.FacilityID 
      inner join um_Type UT on UT.TypeID = J.TypeID 

      cross apply 
      (
       select top 1 Convert(varchar(10), AC.AssignedDate, 20) as AssignedDate from AssignedCase AC 
       where AC.CaseID = C.CaseID 
       ORDER BY AC.AssignedDate DESC 
      ) ASSC 

      cross apply 
      (
       select Convert(varchar(10), min(case when [email protected] then lcs.StatusOnUTC else null end) ,20) BatchStartdate from log_CaseStatus lcs 
       where lcs.CaseID = C.CaseID 
      ) BSD 

      cross apply 
      (
       select sum(case when [email protected] then 1 else 0 end) AccountProcessed from log_AccountStatus la 
       where LA.AccountID = A.AccountID 
      ) LSS 

      cross apply 
      (
       select count(*) as [Errors] from log_AccountError lae 
       where A.AccountID = LAE.AccountID 
      ) ERR 

     )A 
     where 1=1 '[email protected]+'') 


End 
+0

我已经修改我的查询与替换代码的proc存储; ) – Esperento57

+0

感谢您的回复,在这里我找到了所有记录,但我只想记录批处理明智,我们的案例表具有所有批次的详细信息,内批次我们有多个帐户,我的意思是一批可以容纳多个帐户,你注意到我们的4专栏刚刚计数。如果我想使用group by子句,它有可能与否? –

0

下面是删除该功能的新副本。

DECLARE @Condition varchar(max) = --insert value here 
declare @startedstatus uniqueidentifier = --insert value here 
DECLARE @Clarification uniqueidentifier = --insert value here 
DECLARE @Completed uniqueidentifier = --insert value here 
declare @Clarification uniqueidentifier = (select StatusID from MasterStatus where Name=('OnHold') --remove this from funtion so it only executes once 

SELECT DISTINCT 
    J.ReceivedOn ReceivedOn 
    ,CONVERT(varchar(10), J.ReceivedOn, 20) AS ReceivedDate 
    ,UF.Name Facility 
    ,UT.Name [Type] 
    ,C.CaseNumber Batch 
    ,C.ACHA ACHA 
    ,J.Noofaccounts 

    ,[AssignedDate] = (SELECT TOP 1 Convert(varchar(10), AssignedDate, 20) 
     FROM AssignedCase 
     WHERE CaseID = AC.CaseID 
     ORDER BY AssignedDate DESC) 

    ,[BatchStartdate] = Convert(varchar(10), (select top 1 StatusOnUTC 
             from log_CaseStatus 
             where CaseID = C.CaseID 
              and [email protected] 
             order by StatusOnUTC asc),20) 

    ,[AccountProcessed]=(select COUNT(*) 
         from Account ACC inner join log_AccountStatus LA on LA.AccountID = ACC.AccountId 
         where ACC.CaseId = C.CaseID and [email protected]) 

    --,[ClarificationLog] =(select dbo.[Exat_GetClarificationCount](C.CaseID)) 
    --REMOVE FUNCTION FROM STORED PROCEDURE 
    ,[ClarificationLog] =(select COUNT(DISTINCT LA.AccountID) 
          from log_AccountStatus LA 
          inner join Account A 
          on A.AccountID = LA.AccountID 
          where [email protected] 
          and A.CaseId = C.CaseId) 


    ,[Status] = (select Name from [MasterStatus] where StatusId = (select [dbo].[GetStatusIdByCaseID](C.CaseID))) 
    ,[Reviewer] =(select SUBSTRING((SELECT (',' + DisplayName) from um_user where UserID in 
        (select UserID from AssignedCase where CaseID = C.CaseID and [Type] in('DC','Demo','Charges'))FOR XML PATH('')), 2, 1000)) 
    ,[Auditor] =(select SUBSTRING((SELECT (',' + DisplayName) from um_user where UserID in 
        (select ValidatedBy from Account where Validated = 1 and CaseID = C.CaseID)FOR XML PATH('')), 2, 1000)) 
    ,[AuditCount] = (select Count(*) from Account where CaseID = C.CaseID) 
    ,[Errors] = (select Count(*) from log_AccountError LA inner join Account ACO on ACO.AccountID = LA.AccountID where ACO.CaseID = C.CaseID) 

from 
    [Job] J 
     inner join [Case] C 
      on 
      J.JobID = C.JobID 
     inner join log_casestatus lcs 
      on 
      lcs.caseid=c.caseid 
     inner join [Account] A 
      on 
      C.CaseID = A.CaseID 
     inner join [AssignedCase] AC 
      on 
      AC.CaseID = C.CaseID 
     inner join um_Facility UF 
      on 
      UF.FacilityID = J.FacilityID 
     inner join um_Type UT 
      on 
      UT.TypeID = J.TypeID 
     inner join log_AccountStatus LA 
      on LA.AccountID = A.AccountID 
     ; 
+0

谢谢,但是我的老板建议给我替换子查询使用group by子句,因为我们的4列只是通过内连接统计不同表中的记录,怎么实现? –

+0

执行计划将告诉您哪些子查询是最昂贵的,并帮助您决定首先使用GROUP BY处理哪些子查询。 – pacreely

+0

ALTER FUNCTION [DBO]。[Exat_GetClarificationCount](CaseId变量) 返回int AS BEGIN DECLARE @ClarifyCount诠释 \t \t 声明澄清唯一标识符= \t(从MasterStatus其中Name =( '保留状态')选择StatusID)声明AccountDetails表(ACCOUNTID唯一标识符)\t \t INSERT INTO AccountDetails \t从log_AccountStatus LA内选择不同LA.AccountID加入帐户A上A.AccountID = LA.AccountID \t其中LA.StatusID =澄清和A.CaseId = CaseId \t set ClarifyCount =(从AccountDetails中选择Count(*)) \t返回ClarifyCount结束 –