1

嗨我有一个存储过程

     ALTER PROCEDURE [dbo].[usp_EP_GetTherapeuticalALternates]
    (
      @NDCNumber CHAR(11) ,
      @patientid INT ,
      @pbmid INT
    )
AS 
    BEGIN
        TRUNCATE TABLE TempTherapeuticAlt
        INSERT  INTO TempTherapeuticAlt
                SELECT  --PR.ProductID AS MedicationID ,
                        NULL AS MedicationID ,
                        PR.ePrescribingName AS MedicationName ,
                        U.Strength AS MedicationStrength ,
                        FRM.FormName AS MedicationForm ,
                        PR.DEAClassificationID AS DEASchedule ,
                        NULL AS NDCNumber
        --INTO    #myTemp
                FROM    DatabaseTwo.dbo.Product PR
                        JOIN ( SELECT   MP.MarketedProductID
                               FROM     DatabaseTwo.dbo.Therapeutic_Concept_Tree_Specific_Product TCTSP
                                        JOIN DatabaseTwo.dbo.Marketed_Product MP ON MP.SpecificProductID = TCTSP.SpecificProductID
                                        JOIN ( SELECT   TCTSP.TherapeuticConceptTreeID
                                               FROM     DatabaseTwo.dbo.Marketed_Product MP
                                                        JOIN DatabaseTwo.dbo.Therapeutic_Concept_Tree_Specific_Product TCTSP ON MP.SpecificProductID = TCTSP.SpecificProductID
                                                        JOIN ( SELECT
                                                              PR.MarketedProductID
                                                              FROM
                                                              DatabaseTwo.dbo.Package PA
                                                              JOIN DatabaseTwo.dbo.Product PR ON PA.ProductID = PR.ProductID
                                                              WHERE
                                                              PA.NDC11 = @NDCNumber
                                                             ) PAPA ON MP.MarketedProductID = PAPA.MarketedProductID
                                             ) xxx ON TCTSP.TherapeuticConceptTreeID = xxx.TherapeuticConceptTreeID
                             ) MPI ON PR.MarketedProductID = MPI.MarketedProductID
                        JOIN ( SELECT   P.ProductID ,
                                        O.Strength ,
                                        O.Unit
                               FROM     DatabaseTwo.dbo.Product AS P
                                        INNER JOIN DatabaseTwo.dbo.Marketed_Product
                                        AS M ON P.MarketedProductID = M.MarketedProductID
                                        INNER JOIN DatabaseTwo.dbo.Specific_Product
                                        AS S ON M.SpecificProductID = S.SpecificProductID
                                        LEFT OUTER JOIN DatabaseTwo.dbo.OrderableName_Combined
                                        AS O ON S.SpecificProductID = O.SpecificProductID
                               GROUP BY P.ProductID ,
                                        O.Strength ,
                                        O.Unit
                             ) U ON PR.ProductID = U.ProductID
                        JOIN ( SELECT   PA.ProductID ,
                                        S.ScriptFormID ,
                                        F.Code AS NCPDPScriptFormCode ,
                                        S.FormName
                               FROM     DatabaseTwo.dbo.Package AS PA
                                        INNER JOIN DatabaseTwo.dbo.Script_Form
                                        AS S ON PA.NCPDPScriptFormCode = S.NCPDPScriptFormCode
                                        INNER JOIN DatabaseTwo.dbo.FormCode AS F ON S.FormName = F.FormName
                               GROUP BY PA.ProductID ,
                                        S.ScriptFormID ,
                                        F.Code ,
                                        S.FormName
                             ) FRM ON PR.ProductID = FRM.ProductID
                            WHERE   
                            ( PR.OffMarketDate IS NULL )
        OR ( PR.OffMarketDate = '' )
        OR (PR.OffMarketDate = '1899-12-30 00:00:00.000')
        OR ( PR.OffMarketDate <> '1899-12-30 00:00:00.000'
             AND DATEDIFF(dd, GETDATE(),PR.OffMarketDate) > 0
           )
                GROUP BY PR.ePrescribingName ,
                        U.Strength ,
                        FRM.FormName ,
                        PR.DEAClassificationID
               -- ORDER BY pr.ePrescribingName

        SELECT  LL.ProductID AS MedicationID ,
                temp.MedicationName ,
                temp.MedicationStrength ,
                temp.MedicationForm ,
                temp.DEASchedule ,
                temp.NDCNumber ,
                fs.[ReturnFormulary] AS FormularyStatus ,
                copay.CopaTier ,
                copay.FirstCopayTerm ,
                copay.FlatCopayAmount ,
                copay.PercentageCopay ,
                copay.PharmacyType,
                dbo.udf_EP_GetBrandGeneric(LL.ProductID) AS BrandGeneric
        FROM    TempTherapeuticAlt temp
                OUTER APPLY ( SELECT TOP 1
                                        ProductID
                              FROM      DatabaseTwo.dbo.Product
                              WHERE     ePrescribingName = temp.MedicationName
                            ) AS LL
                OUTER APPLY [dbo].[udf_EP_tbfGetFormularyStatus](@patientid,
                                                              LL.ProductID,
                                                              @pbmid) AS fs
                OUTER APPLY ( SELECT TOP 1
                                        *
                              FROM      udf_EP_CopayDetails(LL.ProductID,
                                                            @PBMID,
                                                            fs.ReturnFormulary)
                            ) copay
        --ORDER BY LL.ProductID
        TRUNCATE TABLE TempTherapeuticAlt
    END

在我的开发服务器上,每个表中都有 63k 的数据

所以这个过程大约需要 30 秒才能返回结果。

在我的生产服务器上,它正在超时,或者需要超过 1 分钟。我想知道我的生产服务器表中有 14 亿条记录,

这可能是一个原因。

如果是这样,可以做什么,我在表上有所有必需的索引。

任何帮助将不胜感激。

谢谢

执行计划 http://www.sendspace.com/file/hk8fao

重大泄漏

OUTER APPLY [dbo].[udf_EP_tbfGetFormularyStatus](@patientid,
                                                              LL.ProductID,
                                                              @pbmid) AS fs
4

2 回答 2

4

一些可能有帮助的策略:

  1. 删除第一个 ORDER BY 语句,那些对复杂查询的杀手应该是不必要的。

  2. 使用 CTE 将查询分解为可以单独处理的较小部分。

  3. 减少第一组 JOIN 中的嵌套

  4. 提取第二组和第三组连接(GROUPED 连接)并将它们插入到临时索引表中,然后再连接和分组所有内容。

  5. 您没有包含function1or的定义function2——自定义函数通常是性能问题可以隐藏的地方。

如果没有看到执行计划,就很难看出具体问题可能出在哪里。

于 2012-06-24T00:24:47.707 回答
3

您有一个从 4 或 5 个表中选择数据的查询,其中一些表选择了多次。如果不深入分析您要实现的目标以及实际的表结构,真的很难说如何改进。

数据大小绝对是一个问题;我认为很明显,需要处理的数据越多,查询时间就越长。一些一般性建议... 直接运行查询并检查执行计划。它可能会揭示瓶颈。然后检查统计信息是否是最新的。此外,请查看您的表,在某些情况下,分区可能会有很大帮助。此外,您可以尝试更改表并在 PK 上创建聚集索引(除非另有说明,否则默认情况下会这样做),而是在其他列上创建聚集索引,这样您的查询将受益于某些物理记录顺序。注意:只有在您完全确定自己在做什么时才这样做。

最后,尝试重构您的查询。我觉得有一种更好的方法可以获得所需的结果(对不起,不了解表结构和预期结果我无法说出确切的解决方案,但是同一个表和一堆派生表的多个连接对我来说并不好看)

于 2012-06-24T00:29:39.823 回答