【发布时间】:2011-02-09 14:50:34
【问题描述】:
我有一个存储过程,用于更新用户余额的游戏积分。这是一个带有 5 个子查询的插入。我已将其中一个子查询隔离为减慢整个批处理速度的查询。没有它,存储过程将在 2 秒内运行。有了它,最多需要 8 秒。 8 秒不是世界末日,但为了可扩展性,我需要更快地完成它。这是孤立的子查询:
(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 子句中的函数会评估 每个 行 - 而不是以某种方式缓存函数的定义并以这种方式进行评估。我确实在表上有索引,但我想知道其中一些是否不正确。
如果您不了解完整的数据库结构,我确信很难确定问题出在哪里,但我想指出一个开始进一步隔离的方向。
【问题讨论】:
-
您查看过查询的执行计划吗?这通常会帮助您指出正确的方向。尤其是在预期可能未使用索引或连接成本最高等情况下。
-
是的,这是一个功能......什么是消毒?
标签: sql sql-server join indexing