0

我有一个查询,我需要加快速度:

    SELECT
Distinct Refs.SpecialtyReferredTo
FROM ABI_RiO.dbo.vwSGReferrals Refs
LEFT JOIN ABI_RiO.dbo.vwSGAppointmentsPD Apps ON Refs.ClientID = Apps. ClientID AND Refs.ReferralNumber = Apps.ReferralNumber
LEFT OUTER JOIN ABI_RiO.SchemaSG.AmsOutcome AS AOUT ON AOUT.Code=APPs.Outcome
LEFT JOIN ABI_RiO.SchemaSG.ClientIndex CI ON Refs.ClientID = CI.ClientID
LEFT JOIN ABI_RiO.SchemaSG.GenGPPractice GP ON GP.Code = CI.AIMTCCurrentGPPractice
where Refs.DischargeReason IS NULL
AND ((Apps.ContactID = ISNULL((SELECT Max(Apps2.ContactID)
FROM ABI_RiO.dbo.vwSGReferrals Refs2
LEFT JOIN ABI_RiO.dbo.vwSGAppointmentsPD Apps2 ON Refs2.ClientID = Apps2. ClientID AND Refs2.ReferralNumber = Apps2.ReferralNumber
LEFT OUTER JOIN ABI_RiO.SchemaSG.AmsOutcome AS AOUT ON AOUT.Code=APPs2.Outcome
WHERE Refs2.ClientID = Refs.ClientID
AND Refs2.ReferralNumber = Refs.ReferralNumber
AND NationalCode=5),
(SELECT Max(Apps2.ContactID)
FROM ABI_RiO.dbo.vwSGReferrals Refs2
LEFT JOIN ABI_RiO.dbo.vwSGAppointmentsPD Apps2 ON Refs2.ClientID = Apps2. ClientID AND Refs2.ReferralNumber = Apps2.ReferralNumber
WHERE Refs2.ClientID = Refs.ClientID
AND Refs2.ReferralNumber = Refs.ReferralNumber
))) OR Apps.ContactID IS NULL)
GROUP BY GP.Code, Refs.SpecialtyReferredTo

这需要永远执行。但是,如果我拆分查询的最后一部分,代码将在几秒钟内执行。IE

     SELECT
Distinct GP.Code, Refs.SpecialtyReferredTo
FROM ABI_RiO.dbo.vwSGReferrals Refs
LEFT JOIN ABI_RiO.dbo.vwSGAppointmentsPD Apps ON Refs.ClientID = Apps. ClientID AND Refs.ReferralNumber = Apps.ReferralNumber
LEFT OUTER JOIN ABI_RiO.SchemaSG.AmsOutcome AS AOUT ON AOUT.Code=APPs.Outcome
LEFT JOIN ABI_RiO.SchemaSG.ClientIndex CI ON Refs.ClientID = CI.ClientID
LEFT JOIN ABI_RiO.SchemaSG.GenGPPractice GP ON GP.Code = CI.AIMTCCurrentGPPractice
where Refs.DischargeReason IS NULL
AND ((Apps.ContactID = ((SELECT Max(Apps2.ContactID)
FROM ABI_RiO.dbo.vwSGReferrals Refs2
LEFT JOIN ABI_RiO.dbo.vwSGAppointmentsPD Apps2 ON Refs2.ClientID = Apps2. ClientID AND Refs2.ReferralNumber = Apps2.ReferralNumber
LEFT OUTER JOIN ABI_RiO.SchemaSG.AmsOutcome AS AOUT ON AOUT.Code=APPs2.Outcome
WHERE Refs2.ClientID = Refs.ClientID
AND Refs2.ReferralNumber = Refs.ReferralNumber
AND NationalCode=5))))
GROUP BY GP.Code, Refs.SpecialtyReferredTo
ORDER BY GP.Code

这意味着我的问题在于这里查询的最后一部分:

 (SELECT Max(Apps2.ContactID)
FROM ABI_RiO.dbo.vwSGReferrals Refs2
LEFT JOIN ABI_RiO.dbo.vwSGAppointmentsPD Apps2 ON Refs2.ClientID = Apps2. ClientID AND Refs2.ReferralNumber = Apps2.ReferralNumber
WHERE Refs2.ClientID = Refs.ClientID
AND Refs2.ReferralNumber = Refs.ReferralNumber
))) OR Apps.ContactID IS NULL)
--GROUP BY GP.Code, Refs.SpecialtyReferredTo
--ORDER BY GP.Code

添加最后一个查询块会导致最终输出的数据扩展约 10%。

谁能帮我重新编写这个查询并解释为什么最后一部分会导致执行性能下降。干杯。

R

4

1 回答 1

0

我在这里的第一个倾向是将 ISNULL 部分中的相关子查询更改为两个获取这些值的 OUTER APPLY 计算。

    SELECT
DISTINCT    Refs.SpecialtyReferredTo
    FROM    ABI_RiO.dbo.vwSGReferrals Refs
    LEFT JOIN ABI_RiO.dbo.vwSGAppointmentsPD Apps
    ON      Refs.ClientID = Apps.ClientID
            AND Refs.ReferralNumber = Apps.ReferralNumber
    LEFT OUTER JOIN ABI_RiO.SchemaSG.AmsOutcome AS AOUT
    ON      AOUT.Code = APPs.Outcome
    LEFT JOIN ABI_RiO.SchemaSG.ClientIndex CI
    ON      Refs.ClientID = CI.ClientID
    LEFT JOIN ABI_RiO.SchemaSG.GenGPPractice GP
    ON      GP.Code = CI.AIMTCCurrentGPPractice
OUTER APPLY (select max(Apps2.ContactID) as ContactID1 ...) as OuterApply1
OUTER APPLY (select max(Apps2.ContactID) as ContactID2 ...) as OuterApply2
    WHERE   Refs.DischargeReason IS NULL
AND (Apps.ContactID = ISNULL(ContactID1, ContactID2) or Apps.ContactID IS NULL )

一般来说,当您尝试为每一行计算该相关子查询时,该相关子查询会导致性能问题。将这些计算切换到 OUTER APPLY 至少可以让您将它们作为一组进行处理。

这里有一些 OUTER APPLY 的例子: http ://www.mssqltips.com/sqlservertip/1958/sql-server-cross-apply-and-outer-apply/ 和这里:https://www.simple-talk。 com/sql/t-sql-programming/sql-server-apply-basics/

于 2013-06-10T17:39:33.143 回答