2011-03-19 74 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