【发布时间】:2019-08-05 21:22:34
【问题描述】:
我有一份报告。查询需要几秒钟才能在 Microsoft SSMS (SQL Server Management Studio) 上运行,但每当我通过 Visual Studio 上的 SSRS 运行报告时,现在报告需要几分钟。我已经阅读了很多关于此的内容,每个人都说是它的参数嗅探,但我已经尝试了所有参数嗅探的解决方案,但它们似乎没有做任何事情。
起初,我将所有查询都放在存储过程中。然后,由于我认为将它们作为存储过程可能会导致速度变慢,因此我为报表创建了数据集,其中查询为文本形式。然而,这并没有解决问题。
这是我的查询,它有点长且复杂,但这不是这里的问题。是的,我知道这不是使用 nolock 的正确方法,但这就是我的雇主要求我使用 nolock 的方式。
SELECT DISTINCT
DENSE_RANK() OVER (PARTITION BY O.Customer_Number ORDER BY O.Customer_Purchase_Order_Number ASC)
+ DENSE_RANK() OVER (PARTITION BY O.Customer_Number ORDER BY O.Customer_Purchase_Order_Number DESC)
- 1 AS Total_Orders_Count
,COUNT(*) OVER () AS Total_Units_Count
,Sum(S.Retail * OD.Quantity_Ordered) OVER (PARTITION BY O.Customer_Number) as Total_Net_Value
,Sum(OD.Price * OD.Quantity_Ordered) OVER (PARTITION BY O.Customer_Number) as Price
,Sum(OD.Discount_Value) OVER (PARTITION BY O.Customer_Number) as Discount_Value
,Sum(OD.Freight_Charges) OVER (PARTITION BY O.Customer_Number) as Freight_Charges
,Sum(OD.Tax_Value) OVER (PARTITION BY O.Customer_Number) as Tax_Value
,SUM(CASE WHEN O.Order_Status = '30' then 1 ELSE 0 END) OVER (PARTITION BY O.Customer_Number) as "Cancelled_Orders"
,SUM(CASE WHEN OD.Line_Status = '80' then 1 ELSE 0 END) OVER (PARTITION BY O.Customer_Number) as "Cancelled_Lines"
,Sum (T.Cost) OVER () Total_Product_Cost
,Avg (T.Cost) OVER () Avg_Product_Cost
FROM
[JMNYC-AMTDB].[AMTPLUS].[dbo].Orders O (nolock)
LEFT JOIN
[JMNYC-AMTDB].[AMTPLUS].[dbo].Order_Detail OD (nolock) On O.Company_Code =
OD.Company_Code And O.Division_Code =
OD.Division_Code And O.Control_Number =
OD.Control_Number
LEFT JOIN
[JMNYC-AMTDB].[AMTPLUS].[dbo].[Z_N_RetailPrices] S (nolock) On
OD.Item_Number = S.SKU
LEFT JOIN
(
Select
T.Sku,
CASE WHEN T.AvgCostActual is NULL THEN T.AvgCostStandard ELSE T.AvgCostActual END Cost
From(
Select distinct
Z.Sku,
AVG (CASE WHEN st.Actual_Cost <> 0 THEN st.Actual_Cost ELSE NULL END) OVER (PARTITION BY Z.Sku) AvgCostActual,
AVG (CASE WHEN st.Standard_Cost <> 0 THEN st.Standard_Cost ELSE NULL END) OVER (PARTITION BY Z.Sku) AvgCostStandard
From
[JMNYC-AMTDB].[AMTPLUS].[dbo].[Z_N_RetailPrices] Z
LEFT JOIN
[JMNYC-AMTDB].[AMTPLUS].[dbo].Style St (nolock) On
Z.Sku = St.Item_Number
) T
) T on OD.Item_Number = T.Sku
WHERE
(O.Company_Code = @CompanyCode OR @CompanyCode IS NULL) AND
(O.Division_Code = @DivisionCode OR @DivisionCode IS NULL) AND
o.Customer_Number = 'ecom2x' AND
ISNUMERIC(O.Customer_Purchase_Order_Number) <> 0 AND
o.DateRecordModified BETWEEN @FromDate AND DATEADD(dayofyear, 1, @ToDate)
我可以在 MSSMS 中的查询之前添加它(因为如果我不通过 SSRS 选择参数,我需要声明参数)并且查询会在几秒钟内运行。
DECLARE @CompanyCode VARCHAR(5)
SET @CompanyCode = '03'
DECLARE @DivisionCode VARCHAR(5)
SET @DivisionCode = '001'
DECLARE @FromDate DATETIME
SET @FromDate = '2/1/2019'
DECLARE @ToDate DATETIME
SET @ToDate = '3/1/2019'
在 SSRS 中,使用相同的参数需要几分钟。
我尝试在我的 SSRS 查询中添加以下代码以加快速度(每个人都说这是参数嗅探的解决方案)
Declare @LocalCompanyCode NVARCHAR(5) = @CompanyCode
Declare @LocalDivisionCode NVARCHAR(5)= @DivisionCode
Declare @LocalToDate DATETIME= @ToDate
Declare @LocalFromDate DATETIME= @FromDate
然后更改我的 Where 子句以使用这些局部变量
WHERE
(O.Company_Code = @LocalCompanyCode OR @LocalCompanyCode IS NULL) AND
(O.Division_Code = @LocalDivisionCode OR @LocalDivisionCode IS NULL) AND
o.Customer_Number = 'ecom2x' AND
ISNUMERIC(O.Customer_Purchase_Order_Number) <> 0 AND
o.DateRecordModified BETWEEN @LocalFromDate AND DATEADD(dayofyear, 1,@LocalToDate)
但这改变了一切,查询仍然需要几分钟才能在 SSRS 中运行,而在 SSMS 中运行需要几秒钟。
我也尝试过使用 Recompile,同样的事情。
有人知道我能做什么吗?
【问题讨论】:
-
您是否将数据库跨越到 JMNYC-AMTDB?如果您使用 JMNYC-AMTDB 作为您的数据源,则删除 refs 可能会更快。此外,您的 O.s 在 WHERE 中未大写,这可能会导致性能问题。
-
在查看查询之前,我将在 Visual Studio 内的查询设计器中执行数据集。如果查询在那里运行得很快,它可能只是渲染时间。我有报告查询需要 15 秒,但渲染可能需要 5 分钟。如果报表在服务器上,您可以检查执行日志,但如果不只是在设计器中使用相同的参数运行查询并查看它运行的速度有多快。另一种选择,复制报告,删除所有显示数据并运行的报告项。您不会看到结果,但这意味着它只是在运行查询。
标签: sql sql-server reporting-services ssrs-2008 ssms