2011-03-19 128 views
0

我有帐单应用程序,它具有一些报告生成功能。运行6-7个月后,我面临有线问题。我的sql语句在管理工作室编辑器中完美运行(4秒执行),但是当我将相同的查询放到SP时,需要(1分9秒执行相同的查询)。表有150K行。下面是我在SP中使用的查询。我的应用程序显示超时过期异常消息。我尝试将连接字符串中的超时设置为180秒。 (对于临时解决方案),但没有正面结果。存储过程性能问题

ALTER PROCEDURE [dbo].[rpt_GetShiftEndReport](
@BillDate varchar(10), 
@JobShift int, 
@MonthStartDate varchar(10), 
@MonthEndDate varchar(10) 
) 
AS 
--begin tran 
    SET NOCOUNT ON; 

SELECT  Products.pCode AS ProductCode, MIN(Products.pName) AS ProductName, MIN(Products.pSize) AS ItemSize, MIN(I.gName) AS GroupName, Sales_Trans.Price, 
SUM(Sales_Trans.Sales_Qty) AS SalesQty, SUM(Sales_Trans.Sales_Value) AS SalesValue, SUM(Sales_Trans.Break_Qty) AS BreakQty, 
SUM(Sales_Trans.Break_Value) AS BreakValue, SUM(Sales_Trans.Return_Qty) AS ReturnQty, SUM(Sales_Trans.Return_Value) AS ReturnValue, 
MIN(Products.CloseStock) AS Stock, MIN(Products.pGroup) AS GroupCode, 
dbo.GetCummulativeSales(@MonthStartDate, @MonthEndDate, Products.pCode) AS CummSales 

FROM   Products INNER JOIN 
(SELECT  SalesLog_1.ProductCode, SalesLog_1.Price, SalesLog_1.Quantity AS Sales_Qty, SalesLog_1.Price * SalesLog_1.Quantity AS Sales_Value, 
0 AS Break_Qty, 0 AS Break_Value, 0 AS Return_Qty, 0 AS Return_Value 
FROM   SalesLog AS SalesLog_1 INNER JOIN 
Sales ON SalesLog_1.MemoNo = Sales.MemoNo 
WHERE  (SalesLog_1.BillDate = @BillDate) AND (Sales.JobShift = @JobShift) 
UNION ALL 
SELECT  ProductCode, Price, 0 AS Sales_Qty, 0 AS Sales_Value, 0 AS Break_Qty, 0 AS Break_Value, Quantity AS Return_Qty, 
Price * Quantity AS Return_Value 
FROM   SalesReturn 
WHERE  (BillDate = @BillDate) AND (JobShift = @JobShift) 
UNION ALL 
SELECT  ProductCode, Price, 0 AS Sales_Qty, 0 AS Sales_Value, Quantity AS Break_Qty, Price * Quantity AS Break_Value, 0 AS Return_Qty, 
0 AS Return_Value 
FROM   Breakages 
WHERE  (BillDate = @BillDate) AND (JobShift = @JobShift)) AS Sales_Trans ON Products.pCode = Sales_Trans.ProductCode INNER JOIN 
ItemGroup AS I ON I.gCode = Products.pGroup 
GROUP BY Products.pCode, Sales_Trans.Price 
ORDER BY GroupCode, ItemSize DESC; 

任何人都可以建议我现在该做什么。我不认为它的查询问题可能不会。的行。

+0

您确定您在SP中的参数与查询中的参数值相同(当您不使用SP时)吗? – 2011-03-19 17:57:43

+0

是的,我从SP复制了值到查询 – 2011-03-19 17:59:58

+1

抱歉,声音唠叨......但是,有3个varchar(日期)参数。你有没有确保你为每个值传递了合适的(和期望的)值,并且当你使用SP时,这些参数之间的值没有得到交换?对不起,只是检查.. – 2011-03-19 18:03:41

回答

3

如果您确定sql完全相同并且参数相同,那么您可能会遇到参数嗅探问题。

这是一个非常罕见的问题。我只有一次遇到过这种情况,从那以后,我一直在编写这个问题。

从这里开始对这个问题的简要概述:

http://blogs.msdn.com/b/queryoptteam/archive/2006/03/31/565991.aspx

http://elegantcode.com/2008/05/17/sql-parameter-sniffing-and-what-to-do-about-it/

尝试宣告SP内部的一些局部变量和分配参数的瓦莱斯给他们。使用局部变量代替params。

这是一个功能不是一个错误,但它让你去@“$ @

+0

+1 - “尝试在sp内部声明一些局部变量” - 这可能是性能不佳的头号原因否则根据我的经验正确设计。结果行数和不合适的执行计划差异很大。局部变量是要走的路。 – bic 2011-03-20 00:57:25

0

尝试使用WITH RECOMPILE选项再次下探的过程,然后生成它。这迫使SQLServer的不缓存过程的查询计划。通常这是一件坏事(因为缓存计划可以节省时间,这也是存储过程比同等SQL语句更具性能的主要原因之一),但是在某些情况下,该查询计划不适用于所有值,并因此导致问题。

0

我的朋友帮我解决了这个问题,它是索引谁是罪魁祸首,他创造了新的索引a现在的事情像黄油一样顺利。

感谢所有SO会员,拥有美好的生活。

+0

创建一个新的索引将强制重新编译过程,所以如果问题是参数嗅探,您可能刚刚从缓存中删除了不良计划,问题就会重演。 – 2011-03-20 18:27:35

+0

感谢@马丁我会检查这一点,并会发布更新。感谢您的建议.. – 2011-03-21 06:49:43

+0

@马丁你说得对,它是参数嗅探问题。感谢您的建议 – 2011-03-22 11:26:37