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. 結合の 2 番目と 3 番目のセット (GROUPED のもの) を抽出し、それらを一時的なインデックス テーブルに挿入してから、すべてを結合してグループ化します。

  5. function1orの定義が含まれていませんでしたfunction2-- カスタム関数は、多くの場合、パフォーマンスの問題が隠れる場所です。

実行計画を確認しないと、特定の問題がどこにあるのかを特定することは困難です。

于 2012-06-24T00:24:47.707 に答える
3

4 つまたは 5 つのテーブルからデータを選択するクエリがあり、そのうちのいくつかは複数回使用されます。達成しようとしていることと実際のテーブル構造を深く分析せずに、改善方法を言うのは非常に困難です。

データ サイズは間違いなく問題です。処理するデータが多いほど、クエリにかかる時間が長くなることは明らかだと思います。いくつかの一般的なアドバイス... クエリを直接実行し、実行計画を確認します。ボトルネックが明らかになる場合があります。次に、統計が最新かどうかを確認します。また、テーブルを確認してください。場合によっては、パーティショニングが非常に役立つ場合があります。さらに、テーブルを変更して、PK ではなくクラスター化インデックスを作成することもできます (特に指定されていない限り、既定で行われます)。ただし、他の列でクエリがレコードの特定の物理順序の恩恵を受けるようにします。注意 : 何をしているのか完全に確信している場合にのみ実行してください。

最後に、クエリをリファクタリングしてみてください。望ましい結果を得るためのより良い方法があると感じています (申し訳ありませんが、テーブルの構造と期待される結果を理解していないため、正確な解決策はわかりませんが、同じテーブルと一連の派生テーブルの複数の結合は、私にはよく見えません)

于 2012-06-24T00:29:39.823 に答える