SQL Тот же самый запрос выполняется быстро в первый раз и медленно во второй раз.А потом чередует - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть запрос.Когда я запускаю его в первый раз, он мгновенно возвращается.Примерно через секунду.Затем, когда я нажал F5, чтобы снова запустить ту же самую вещь без изменений, теперь она работает медленно, занимая более 30 секунд.Затем, если я снова нажму F5, он снова запускается мгновенно.И так далее, и он продолжает чередоваться.

Вот запрос:

IF @LocalDetailLevel = 'master'
BEGIN

    SELECT * FROM (
        SELECT DISTINCT

        Master_Item
        ,'--' Item_Number
        ,'--' Color_Code 
        ,Description
        ,'--' Color_Description

        ,SUM(Unit_Retail) Sum_Unit_Retail
        ,AVG(Unit_Retail)  Avg_Unit_Retail

        ,SUM(Unit_MarkDown)  Sum_Unit_MarkDown
        ,AVG(Unit_MarkDown)  Avg_Unit_MarkDown
        ,AVG(Unit_MarkDown_Percent)  Avg_Unit_MarkDown_Percent

        ,SUM(Sell_Price)  Sum_Sell_Price
        ,AVG(Sell_Price)  Avg_Sell_Price

        ,SUM(Discount_Value)  Sum_Discount_Value
        ,AVG(Discount_Value)  Avg_Discount_Value
        ,AVG(Unit_Discount_Value_Percent)  Avg_Discount_Value_Percent

        ,SUM(Sale_Price)  Sum_Sale_Price
        ,AVG(Sale_Price)  Avg_Sale_Price

        ,SUM(Royalty_Cost)  Sum_Royalty_Cost
        ,AVG(Royalty_Cost)  Avg_Royalty_Cost
        ,AVG(Unit_Royalty_Cost_Percent)  Avg_Royalty_Cost_Percent

        ,SUM(Item_Cost)  Sum_Item_Cost
        ,AVG(Item_Cost)  Avg_Item_Cost
        ,AVG(Unit_Item_Cost_Percent)  Avg_Item_Cost_Percent

        ,SUM(Order_Gross_Profit_Minus_Discounts_And_Royalty_And_Freight)  Sum_Gross_Profit
        ,AVG(Order_Gross_Profit_Minus_Discounts_And_Royalty_And_Freight)  Avg_Gross_Profit
        ,AVG(Order_Gross_Profit_Minus_Discounts_And_Royalty_And_Freight_Percent)  Avg_Gross_Profit_Percent

        ,MAX(Quantity_Invoiced+Quantity_Allocated)  Max_Quantity

        ,SUM(Quantity_Invoiced+Quantity_Allocated)  Total_Units

        ,COUNT(DISTINCT Customer_Purchase_Order_Number ) Total_Orders_Cont
        ,-1 Percent_Of_Orders_Cont

        ,SUM(Quantity_Invoiced+Quantity_Allocated) / COUNT(DISTINCT Customer_Purchase_Order_Number) Average_Order_Quantity

        ,SUM(Quantity_Returned)  Total_Units_Returned
        ,MAX(Quantity_Returned)  Max_Quantity_Returned
        ,SUM(Quantity_Returned)  
        /NULLIF(SUM(Quantity_Invoiced+Quantity_Allocated) ,0) Return_Percentage

        ,SUM(CASE WHEN F.Line_Status = 'CANCELLED' THEN Quantity_Ordered ELSE 0 END)  Cancelled_Count
        ,SUM(CASE WHEN F.Line_Status = 'CANCELLED' THEN Quantity_Ordered ELSE 0 END)  
        / NULLIF(SUM(Quantity_Ordered) ,0) Cancelled_Count_Percent

        ,SUM(CASE WHEN (Tags not like '%customerrequested_cancel%' and Tags not like '%ia_cancel%' and (FulfillmentState like 'partial%' or FinancialState like 'partial%')) THEN Short_Shipped ELSE 0 END)  Short_Shipped_Count
        ,SUM(CASE WHEN (Tags not like '%customerrequested_cancel%' and Tags not like '%ia_cancel%' and (FulfillmentState like 'partial%' or FinancialState like 'partial%')) THEN Short_Shipped ELSE 0 END)  
        / NULLIF(SUM(Quantity_Ordered) ,0) Short_Shipped_Count_Percent

    FROM 
        FinalEcomTable F

    WHERE
        1=1
        AND (F.Company_Code = @LocalCompanyCode OR @LocalCompanyCode IS NULL)  
        AND (F.Division_Code = @LocalDivisionCode OR @LocalDivisionCode IS NULL)
        AND F.Coal_Date BETWEEN @LocalFromDate AND DATEADD(dayofyear, 1, @LocalToDate)

    GROUP BY Master_Item, Item_Number, Color_Code, Description, Color_Description


    ) T

    ORDER BY  
        CASE WHEN @LocalOrderBy = 'ordered' THEN Total_Units END DESC, 
        CASE WHEN @LocalOrderBy = 'returned' THEN Total_Units_Returned END DESC,
        CASE WHEN @LocalOrderBy = 'cancelled' THEN Cancelled_Count END DESC,
        CASE WHEN @LocalOrderBy = 'shortshipped' THEN Short_Shipped_Count END DESC

    --OPTION    (RECOMPILE)

END

IF @LocalDetailLevel = 'size'
BEGIN

    SELECT * FROM (
        SELECT DISTINCT

        Master_Item
        ,Item_Number
        ,'--' Color_Code 
        ,Description
        ,'--' Color_Description
        ,SUM(Unit_Retail)  Sum_Unit_Retail
        ,AVG(Unit_Retail)  Avg_Unit_Retail

        ,SUM(Unit_MarkDown)  Sum_Unit_MarkDown
        ,AVG(Unit_MarkDown)  Avg_Unit_MarkDown
        ,AVG(Unit_MarkDown_Percent)  Avg_Unit_MarkDown_Percent

        ,SUM(Sell_Price)  Sum_Sell_Price
        ,AVG(Sell_Price)  Avg_Sell_Price

        ,SUM(Discount_Value)  Sum_Discount_Value
        ,AVG(Discount_Value)  Avg_Discount_Value
        ,AVG(Unit_Discount_Value_Percent)  Avg_Discount_Value_Percent

        ,SUM(Sale_Price)  Sum_Sale_Price
        ,AVG(Sale_Price)  Avg_Sale_Price

        ,SUM(Royalty_Cost)  Sum_Royalty_Cost
        ,AVG(Royalty_Cost)  Avg_Royalty_Cost
        ,AVG(Unit_Royalty_Cost_Percent)  Avg_Royalty_Cost_Percent

        ,SUM(Item_Cost)  Sum_Item_Cost
        ,AVG(Item_Cost)  Avg_Item_Cost
        ,AVG(Unit_Item_Cost_Percent)  Avg_Item_Cost_Percent

        ,SUM(Order_Gross_Profit_Minus_Discounts_And_Royalty_And_Freight)  Sum_Gross_Profit
        ,AVG(Order_Gross_Profit_Minus_Discounts_And_Royalty_And_Freight)  Avg_Gross_Profit
        ,AVG(Order_Gross_Profit_Minus_Discounts_And_Royalty_And_Freight_Percent)  Avg_Gross_Profit_Percent

        ,MAX(Quantity_Invoiced+Quantity_Allocated)  Max_Quantity

        ,SUM(Quantity_Invoiced+Quantity_Allocated)  Total_Units

        ,COUNT(DISTINCT Customer_Purchase_Order_Number) Total_Orders_Cont
        ,-1 Percent_Of_Orders_Cont

        ,SUM(Quantity_Invoiced+Quantity_Allocated) / COUNT(DISTINCT Customer_Purchase_Order_Number) Average_Order_Quantity

        ,SUM(Quantity_Returned)  Total_Units_Returned
        ,MAX(Quantity_Returned)  Max_Quantity_Returned
        ,SUM(Quantity_Returned)  
        /NULLIF(SUM(Quantity_Invoiced+Quantity_Allocated) ,0) Return_Percentage

        ,SUM(CASE WHEN F.Line_Status = 'CANCELLED' THEN Quantity_Ordered ELSE 0 END)  Cancelled_Count
        ,SUM(CASE WHEN F.Line_Status = 'CANCELLED' THEN Quantity_Ordered ELSE 0 END)  
        / NULLIF(SUM(Quantity_Ordered) ,0) Cancelled_Count_Percent

        ,SUM(CASE WHEN (Tags not like '%customerrequested_cancel%' and Tags not like '%ia_cancel%' and (FulfillmentState like 'partial%' or FinancialState like 'partial%')) THEN Short_Shipped ELSE 0 END)  Short_Shipped_Count
        ,SUM(CASE WHEN (Tags not like '%customerrequested_cancel%' and Tags not like '%ia_cancel%' and (FulfillmentState like 'partial%' or FinancialState like 'partial%')) THEN Short_Shipped ELSE 0 END)  
        / NULLIF(SUM(Quantity_Ordered) ,0) Short_Shipped_Count_Percent


    FROM 
        FinalEcomTable F

    WHERE
        1=1
        AND (F.Company_Code = @LocalCompanyCode OR @LocalCompanyCode IS NULL)  
        AND (F.Division_Code = @LocalDivisionCode OR @LocalDivisionCode IS NULL)
        AND F.Coal_Date BETWEEN @LocalFromDate AND DATEADD(dayofyear, 1, @LocalToDate)

    GROUP BY Master_Item, Item_Number, Color_Code, Description, Color_Description

    ) T

    ORDER BY  
        CASE WHEN @LocalOrderBy = 'ordered' THEN Total_Units END DESC, 
        CASE WHEN @LocalOrderBy = 'returned' THEN Total_Units_Returned END DESC,
        CASE WHEN @LocalOrderBy = 'cancelled' THEN Cancelled_Count END DESC,
        CASE WHEN @LocalOrderBy = 'shortshipped' THEN Short_Shipped_Count END DESC

    --OPTION    (RECOMPILE)

END

IF @LocalDetailLevel = 'color'
BEGIN

    SELECT * FROM (
        SELECT DISTINCT

        Master_Item
        ,Item_Number
        ,Color_Code 
        ,Description
        ,Color_Description
        ,SUM(Unit_Retail)  Sum_Unit_Retail
        ,AVG(Unit_Retail)  Avg_Unit_Retail

        ,SUM(Unit_MarkDown)  Sum_Unit_MarkDown
        ,AVG(Unit_MarkDown)  Avg_Unit_MarkDown
        ,AVG(Unit_MarkDown_Percent)  Avg_Unit_MarkDown_Percent

        ,SUM(Sell_Price)  Sum_Sell_Price
        ,AVG(Sell_Price)  Avg_Sell_Price

        ,SUM(Discount_Value)  Sum_Discount_Value
        ,AVG(Discount_Value)  Avg_Discount_Value
        ,AVG(Unit_Discount_Value_Percent)  Avg_Discount_Value_Percent

        ,SUM(Sale_Price)  Sum_Sale_Price
        ,AVG(Sale_Price)  Avg_Sale_Price

        ,SUM(Royalty_Cost)  Sum_Royalty_Cost
        ,AVG(Royalty_Cost)  Avg_Royalty_Cost
        ,AVG(Unit_Royalty_Cost_Percent)  Avg_Royalty_Cost_Percent

        ,SUM(Item_Cost)  Sum_Item_Cost
        ,AVG(Item_Cost)  Avg_Item_Cost
        ,AVG(Unit_Item_Cost_Percent)  Avg_Item_Cost_Percent

        ,SUM(Order_Gross_Profit_Minus_Discounts_And_Royalty_And_Freight)  Sum_Gross_Profit
        ,AVG(Order_Gross_Profit_Minus_Discounts_And_Royalty_And_Freight)  Avg_Gross_Profit
        ,AVG(Order_Gross_Profit_Minus_Discounts_And_Royalty_And_Freight_Percent)  Avg_Gross_Profit_Percent

        ,MAX(Quantity_Invoiced+Quantity_Allocated)  Max_Quantity

        ,SUM(Quantity_Invoiced+Quantity_Allocated)  Total_Units

        ,COUNT(DISTINCT Customer_Purchase_Order_Number) Total_Orders_Cont
        ,-1 Percent_Of_Orders_Cont

        ,SUM(Quantity_Invoiced+Quantity_Allocated) / COUNT(DISTINCT Customer_Purchase_Order_Number) Average_Order_Quantity

        ,SUM(Quantity_Returned)  Total_Units_Returned
        ,MAX(Quantity_Returned)  Max_Quantity_Returned
        ,SUM(Quantity_Returned)  
        /NULLIF(SUM(Quantity_Invoiced+Quantity_Allocated) ,0) Return_Percentage

        ,SUM(CASE WHEN F.Line_Status = 'CANCELLED' THEN Quantity_Ordered ELSE 0 END)  Cancelled_Count
        ,SUM(CASE WHEN F.Line_Status = 'CANCELLED' THEN Quantity_Ordered ELSE 0 END)  
        / NULLIF(SUM(Quantity_Ordered) ,0) Cancelled_Count_Percent

        ,SUM(CASE WHEN (Tags not like '%customerrequested_cancel%' and Tags not like '%ia_cancel%' and (FulfillmentState like 'partial%' or FinancialState like 'partial%')) THEN Short_Shipped ELSE 0 END)  Short_Shipped_Count
        ,SUM(CASE WHEN (Tags not like '%customerrequested_cancel%' and Tags not like '%ia_cancel%' and (FulfillmentState like 'partial%' or FinancialState like 'partial%')) THEN Short_Shipped ELSE 0 END)  
        / NULLIF(SUM(Quantity_Ordered) ,0) Short_Shipped_Count_Percent

    FROM 
        FinalEcomTable F

    WHERE
        1=1
        AND (F.Company_Code = @LocalCompanyCode OR @LocalCompanyCode IS NULL)  
        AND (F.Division_Code = @LocalDivisionCode OR @LocalDivisionCode IS NULL)
        AND F.Coal_Date BETWEEN @LocalFromDate AND DATEADD(dayofyear, 1, @LocalToDate)

    GROUP BY Master_Item, Item_Number, Color_Code, Description, Color_Description

    ) T

    ORDER BY  
        CASE WHEN @LocalOrderBy = 'ordered' THEN Total_Units END DESC, 
        CASE WHEN @LocalOrderBy = 'returned' THEN Total_Units_Returned END DESC,
        CASE WHEN @LocalOrderBy = 'cancelled' THEN Cancelled_Count END DESC,
        CASE WHEN @LocalOrderBy = 'shortshipped' THEN Short_Shipped_Count END DESC

    --OPTION    (RECOMPILE)

END

Я предполагаю, что это связано с тем, что компилятор пытается оптимизировать мой запрос.Как мне сделать так, чтобы он оптимизировал для "@LocalDetailLevel = 'color'", так как это будет использоваться в 90% случаев?

Если кто-то может сказать мне, как добавить

OPTION (OPTIMIZE FOR (@LocalDetailLevel = 'color'))

в мою хранимую процедуру, я думаю, что это решит многие мои проблемы.Моя хранимая процедура:

GO
/****** Object:  StoredProcedure [dbo].[Z_N_FinalEcomDashAllItems]    Script Date: 9/24/2019 12:20:31 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
ALTER PROC [dbo].[ZZ_N_FinalEcomDashAllItems] 

@CompanyCode    VARCHAR(5),
@DivisionCode   VARCHAR(5),
@FromDate       DATETIME,
@ToDate         DATETIME,
@DetailLevel    VARCHAR(50),
@OrderBy    VARCHAR(50)


AS

DECLARE @LocalCompanyCode VARCHAR(5)
SET @LocalCompanyCode = @CompanyCode

DECLARE @LocalDivisionCode VARCHAR(5)
SET @LocalDivisionCode = @DivisionCode

DECLARE @LocalFromDate DATETIME
SET @LocalFromDate = @FromDate

DECLARE @LocalToDate DATETIME
SET @LocalToDate = @ToDate

DECLARE @LocalDetailLevel VARCHAR(50)
SET @LocalDetailLevel = @DetailLevel

DECLARE @LocalOrderBy VARCHAR(50)
SET @LocalOrderBy = @OrderBy

BEGIN
... The query from above
END

Я пытался добавить ее следующим образом

BEGIN
... The query from above
OPTION (OPTIMIZE FOR (@LocalDetailLevel = 'color'))
END

Но там написано "Неверный синтаксис рядом с ключевым словом" OPTION ". *

ЕслиЯ избавляюсь от всех BEGIN / END после предложения IF и имею только один начальный конец для всей процедуры, я получаю «Переменная« @LocalDetailLevel »указана в предложении OPTIMIZE FOR, но не используется в запросе.«

...