Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 存储过程性能改进_Sql_Sql Server - Fatal编程技术网

Sql 存储过程性能改进

Sql 存储过程性能改进,sql,sql-server,Sql,Sql Server,请检查下面的Microsoft SQL StoredProcess查询。有了这个问题,我完成这个过程变得非常缓慢。对于仅1000/2000条记录,执行时间超过20秒。现在我的问题是如何调整此查询以提高其性能?我不需要整个工作查询,但我需要专家的建议,我可以做什么来提高其性能?有没有更好的短方法来编写相同的查询?请给我一些建议。提前谢谢 性能差的SQL: USE [Analytics] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO AL

请检查下面的Microsoft SQL StoredProcess查询。有了这个问题,我完成这个过程变得非常缓慢。对于仅1000/2000条记录,执行时间超过20秒。现在我的问题是如何调整此查询以提高其性能?我不需要整个工作查询,但我需要专家的建议,我可以做什么来提高其性能?有没有更好的短方法来编写相同的查询?请给我一些建议。提前谢谢

性能差的SQL:

USE [Analytics]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


ALTER procedure [vision].[SancusoReferralExceptionsReport]
as
begin
 Declare @programid varchar(30) ;
 DECLARE @Startdate DATETIME = '1900-01-01'
 set @programid = '31';
     ;        
     with ProgramExceptions as
     (

            -- 1. Referring contact name should not be blank
           select 'Referral Pharmacy Contact Name should not be blank' as ExceptionReason
                 , a.AspnRxID
                 , ap.PrescriptionID
              from [ArmadaRX].aspn.ASPNRX a  
              left outer join [ArmadaRX].aspn.ASPNRX_PRESCRIPTION ap on ap.AspnRxID = a.AspnRxID
              where a.ProgramID in (31)
              and (@Startdate is null or (a.CreatedOn between @Startdate and getdate()))
              and (a.ReferringPharmacyContact is null or rtrim(ltrim(a.ReferringPharmacyContact)) = '')


            union
            -- 2.   Received/Referral Date should not be blank
            select 'Received/Referral date should not be blank' as ExceptionReason
                  , a.AspnRxID
                  , ap.PrescriptionID
            from [ArmadaRX].aspn.ASPNRX a 
            left outer join [ArmadaRX].aspn.ASPNRX_PRESCRIPTION ap on ap.AspnRxID = a.AspnRxID
            where a.ProgramID in (31)
            and (@Startdate is null or (a.CreatedOn between @Startdate and getdate()))
            and a.ReceivedOn is null


     ) /* end of CTE */


           select distinct
                  pe.ExceptionReason
                , pe.AspnRxID 
                , a.ProgramID
                , prg.ProgramName
                , coalesce(cp.ReferralType,a.ReferralType) ReferralType
                , a.RxType
                , a.ProgramStatus
                , a.ProgramSubstatus
                , a.ReceivedOn as ReceivedOnDate
                , a.PrescriptionDate
                , ap.FillDate
                , ap.ShipDate   
                , cp.Quantity as PrescriptionQuantity
                , ap.FillQty
                , ap.Indicator
                , a.CreatedOn as CreateDate
                , a.ModifiedOn as ModifyDate
                , a.AssignedOn as AssignDate
                , a.AcceptedOn as AcceptDate
                , a.CompletedOn as CompleteDate
                , a.CancelledOn as CancelDate
                , a.FillingPharmacyContact
                , a.ReferringPharmacyContact
                , m.MemberName as FillingPharmacyName
                , m2.MemberName as ReferringPharmacyName
                , cp.PrescriptionID
                , cp.DrugName
                , cp.Copay as PrescriptionCopay
                , a.ReferralCode
                , (select [TypeCode] from [ArmadaRX].[common].[INSURANCETYPE] where [InsuranceTypeID] = cp.InsuranceType) as InsuranceType
                , cp.InsuranceName
                , pd.NPI
                , cp.Binnumber

        from ProgramExceptions pe
          inner join [ArmadaRX].aspn.ASPNRX a on a.AspnRxID = pe.AspnRxID
          left outer join [ArmadaRX].aspn.ASPNRX_PRESCRIPTION ap on ap.AspnRxID = pe.AspnRxID and (pe.PrescriptionID is null or ap.PrescriptionID = pe.PrescriptionID)  
          left outer join [ArmadaRX].common.PRESCRIPTION cp on cp.PrescriptionID = ap.PrescriptionID and (pe.PrescriptionID is null or cp.PrescriptionID = pe.PrescriptionID)
          left outer join ArmadaRX.aspn.PRESCRIPTIONDOCTOR pd on pd.PrescriptionID = cp.PrescriptionID
          left outer join [ArmadaRX].common.Patient p on p.patientID = a.PatientID
          left outer join [ArmadaRX].aspn.Program prg on prg.ProgramID = a.ProgramID
          left outer join ArmadaApproveRx.dbo.vMember m on m.MemberID = a.FillingPharmacyID
          left outer join ArmadaApproveRx.dbo.vMember m2 on m2.MemberID = a.ReferringPharmacyID

         where a.ProgramID in (31)
        order by pe.AspnRxID



end 

根据我的经验,对大型数据集使用CTE会降低查询的性能。在将CTE转换为临时表的过程中,我发现性能有了很大的提高,因为这确实使我能够根据需要创建索引。下面的代码是使用CTE将OPs示例查询转换为使用临时表的示例

USE [Analytics]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


ALTER procedure [vision].[SancusoReferralExceptionsReport]
as
begin
 Declare @programid varchar(30) ;
 DECLARE @Startdate DATETIME = '1900-01-01'
 set @programid = '31';

SELECT * 
INTO #TempTable
FROM (
    -- 1. Referring contact name should not be blank
   select 'Referral Pharmacy Contact Name should not be blank' as ExceptionReason
         , a.AspnRxID
         , ap.PrescriptionID
      from [ArmadaRX].aspn.ASPNRX a  
      left outer join [ArmadaRX].aspn.ASPNRX_PRESCRIPTION ap on ap.AspnRxID = a.AspnRxID
      where a.ProgramID in (31)
      and (@Startdate is null or (a.CreatedOn between @Startdate and getdate()))
      and (a.ReferringPharmacyContact is null or rtrim(ltrim(a.ReferringPharmacyContact)) = '')


    union
    -- 2.   Received/Referral Date should not be blank
    select 'Received/Referral date should not be blank' as ExceptionReason
          , a.AspnRxID
          , ap.PrescriptionID
    from [ArmadaRX].aspn.ASPNRX a 
    left outer join [ArmadaRX].aspn.ASPNRX_PRESCRIPTION ap on ap.AspnRxID = a.AspnRxID
    where a.ProgramID in (31)
    and (@Startdate is null or (a.CreatedOn between @Startdate and getdate()))
    and a.ReceivedOn is null
 ) AS T
select distinct
      pe.ExceptionReason
    , pe.AspnRxID 
    , a.ProgramID
    , prg.ProgramName
    , coalesce(cp.ReferralType,a.ReferralType) ReferralType
    , a.RxType
    , a.ProgramStatus
    , a.ProgramSubstatus
    , a.ReceivedOn as ReceivedOnDate
    , a.PrescriptionDate
    , ap.FillDate
    , ap.ShipDate   
    , cp.Quantity as PrescriptionQuantity
    , ap.FillQty
    , ap.Indicator
    , a.CreatedOn as CreateDate
    , a.ModifiedOn as ModifyDate
    , a.AssignedOn as AssignDate
    , a.AcceptedOn as AcceptDate
    , a.CompletedOn as CompleteDate
    , a.CancelledOn as CancelDate
    , a.FillingPharmacyContact
    , a.ReferringPharmacyContact
    , m.MemberName as FillingPharmacyName
    , m2.MemberName as ReferringPharmacyName
    , cp.PrescriptionID
    , cp.DrugName
    , cp.Copay as PrescriptionCopay
    , a.ReferralCode
    , (select [TypeCode] from [ArmadaRX].[common].[INSURANCETYPE] where [InsuranceTypeID] = cp.InsuranceType) as InsuranceType
    , cp.InsuranceName
    , pd.NPI
    , cp.Binnumber
from #TempTable pe
  inner join [ArmadaRX].aspn.ASPNRX a on a.AspnRxID = pe.AspnRxID
  left outer join [ArmadaRX].aspn.ASPNRX_PRESCRIPTION ap on ap.AspnRxID = pe.AspnRxID and (pe.PrescriptionID is null or ap.PrescriptionID = pe.PrescriptionID)  
  left outer join [ArmadaRX].common.PRESCRIPTION cp on cp.PrescriptionID = ap.PrescriptionID and (pe.PrescriptionID is null or cp.PrescriptionID = pe.PrescriptionID)
  left outer join ArmadaRX.aspn.PRESCRIPTIONDOCTOR pd on pd.PrescriptionID = cp.PrescriptionID
  left outer join [ArmadaRX].common.Patient p on p.patientID = a.PatientID
  left outer join [ArmadaRX].aspn.Program prg on prg.ProgramID = a.ProgramID
  left outer join ArmadaApproveRx.dbo.vMember m on m.MemberID = a.FillingPharmacyID
  left outer join ArmadaApproveRx.dbo.vMember m2 on m2.MemberID = a.ReferringPharmacyID

where a.ProgramID in (31)
order by pe.AspnRxID

DROP TABLE #TempTable

end

检查与日期相关的列日期有什么问题?你能详细解释一下吗?我不喜欢保险类型的子选择。您不能将其设置为常规联接吗?
有没有更好的短方法来编写相同的查询?
我们的任务跟踪器中没有包含所有需求和数据模型描述的任务。因此,用任何其他给出相同输出的连接和/或谓词列表重写它,对我们任何人来说都肯定是棘手的。你有实际的执行计划吗?您是否需要所有这些distincts和跨数据库联接?当
@Startdate
从不为空时,为什么查询检查
@Startdate为空!顺便说一句,这项工作做得很好,但如果您添加一些解释,这将更有帮助。根据我的经验,对大型数据集使用CTE会降低查询的性能。在将CTE转换为临时表的过程中,我发现性能有了很大的提高,因为这确实使我能够根据需要创建索引。上面的代码是使用CTE将OPs示例查询转换为使用临时表的示例。