我有一個存儲過程運行以更新用戶餘額的遊戲點。這是一個插入5個子查詢。我已經隔離了其中一個子查詢作爲減慢整個批次的查詢。沒有它,存儲過程將在2秒內運行。有了它,它將需要多達8秒。 8秒不是世界末日,但爲了可擴展性,我需要更快完成。這裏是隔離的子查詢:幫助改進SQL加入
(SELECT IsNull(Sum(A.TransAmount) + Sum(Case When A.BetResult = 1 Then (A.BetWinAmount + (A.TransAmount * -1)) End), 0)
FROM User_T A
LEFT OUTER JOIN User_TD B on A.TID = B.TID
LEFT OUTER JOIN Lines_BL C ON B.LID = C.LID
LEFT OUTER JOIN Lines_BM D ON C.BMID = D.BMID
LEFT OUTER JOIN Event_M E ON D.EID = E.EID
LEFT OUTER JOIN Event_KB F ON A.TransReason = F.BID
LEFT OUTER JOIN Event_M G ON F.BID = G.EID
where A.UserID = U.UserID AND (A.IsSettled = 1)
AND
(
(A.TransReason = 1 AND (datediff(dd, Convert(datetime, E.EDate, 101), Convert(datetime, @EndDate, 101)) = @DaysAgo)) OR
(A.TransReason >= 3000 AND (datediff(dd, Convert(datetime, G.EDate, 101), Convert(datetime, @EndDate, 101)) = @DaysAgo)
AND [dbo].[Event_CEAFKBID](A.TransReason) = 1) OR
(A.TransReason BETWEEN 3 and 150 AND (datediff(dd, Convert(datetime, A.TransDT, 101), Convert(datetime, @EndDate, 101)) = @DaysAgo))
)
我做了什麼,以進一步孤立:當我剛剛加入運行SELECT *(沒有where子句),性能非常不錯 - > 100000行的下一個第二。正如我在where子句中所加的那樣,我認爲減慢的好處來自'or'子句和/或需要評估的函數。
據我所知,where子句中的函數計算每行行 - 而不是以某種方式緩存函數的定義並評估該方式。我在桌子上有索引,但我想知道他們中有些是不正確的。如果沒有你知道完整的數據庫結構,我相信很難找出問題所在,但我想指出一個方向開始進一步隔離。
您是否看過查詢的執行計劃?這通常會幫助你指出正確的方向。特別是在預期不能使用痕跡的情況下,或者哪些連接是最昂貴的情況下。 –
是的,這是一項功能...什麼是淨化? – IMAbev