Search code examples
stored-proceduresquery-optimizationuser-defined-functionsindices

Sql Server queries optimization techniques


My Stored Procedure takes a very long time to execute. Can anyone suggest me what I can do to speed up the stored procedure, apart from using some good practices for writing down the queries. I've heard about creating indices, but I'm not sure what are they. Please suggest all the best ways to speed up my queries. Thanks

CREATE PROCEDURE [dbo].[usp_GetAlternates]
(
  @NNumber CHAR(11) ,
  @pid INT ,
  @pbmid INT
)
AS 
BEGIN
    TRUNCATE TABLE TempTherapeuticAlt
    INSERT  INTO TempTherapeuticAlt
            SELECT  NULL AS MedicationID ,
                    PR.ePrescribingName AS MedicationName ,
                    U.Strength AS MedicationStrength ,
                    FRM.FormName AS MedicationForm ,
                    PR.DEAClassificationID AS DEASchedule ,
                    NULL AS NDCNumber
            FROM    Product PR
                    JOIN ( SELECT   MP.MarketedProductID
                           FROM     table2 TCTSP
                                    JOIN table3 MP ON MP.SpecificProductID = TCTSP.SpecificProductID
                                    JOIN ( SELECT   TCTSP.TherapeuticConceptTreeID
                                           FROM     table3 MP
                                                    JOIN table2 TCTSP ON MP.SpecificProductID = TCTSP.SpecificProductID
                                                    JOIN ( SELECT
                                                          PR.MarketedProductID
                                                          FROM
                                                          table4 PA
                                                          JOIN Product PR ON PA.ProductID = PR.ProductID
                                                          WHERE
                                                          PA.NDC11 = @NNumber
                                                         ) 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     Product AS P
                                    INNER JOIN table3 AS M ON P.MarketedProductID = M.MarketedProductID
                                    INNER JOIN table5 AS S ON M.SpecificProductID = S.SpecificProductID
                                    LEFT OUTER JOIN table6 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     table4 AS PA
                                    INNER JOIN table7 AS S ON PA.NCPDPScriptFormCode = S.NCPDPScriptFormCode
                                    INNER JOIN table8 AS F ON S.FormName = F.FormName
                           GROUP BY PA.ProductID ,
                                    S.ScriptFormID ,
                                    F.Code ,
                                    S.FormName
                         ) FRM ON PR.ProductID = FRM.ProductID
            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
    FROM    TempTherapeuticAlt temp
            OUTER APPLY ( SELECT TOP 1
                                    ProductID
                          FROM      Product
                          WHERE     ePrescribingName = temp.MedicationName
                        ) AS LL
            OUTER APPLY function1(@pid, LL.ProductID, @pbmid) AS fs
            OUTER APPLY function2(LL.ProductID, @pbmid) AS copay
    ORDER BY LL.ProductID

    TRUNCATE TABLE TempTherapeuticAlt
END

GO


Solution

  • Here are a few:

    1. You should have indexes for every column in a WHERE clause. See your SQL language for how to do it.
    2. Learn how to EXPLAIN PLAN and see what's slow.
    3. Stored procedure languages are functional, not set based. Use JOIN and don't fall into the (n+1) query/iteration trap.
    4. Understand how using certain functions force you to TABLE SCAN in a WHERE clause.