我正在使用SQL Server 2012。
当我运行此查询时......
select
count(*)
from
MembershipStatusHistory msh
join
gym.Account a on msh.AccountID = a.AccountID
join
gym.MembershipType mt on a.MembershipTypeID = mt.MembershipTypeID
join
MemberTypeGroups mtg on mt.MemberTypeGroupID = mtg.MemberTypeGroupID
where
mtg.MemberTypeGroupID IN (1,2)
and msh.NewMembershipStatus = 'Cancelled'
and year(msh.ChangeDate) = year(getdate())
and month(msh.ChangeDate) = month(getdate())
and day(msh.ChangeDate) = day(getdate())
......它几乎立即返回。大。现在,当我像这样运行相同的确切查询时:
declare @CancellationsToday int
SET @CancellationsToday = (
select
count(*)
from MembershipStatusHistory msh
join gym.Account a
on msh.AccountID = a.AccountID
join gym.MembershipType mt
on a.MembershipTypeID = mt.MembershipTypeID
join MemberTypeGroups mtg
on mt.MemberTypeGroupID = mtg.MemberTypeGroupID
where mtg.MemberTypeGroupID IN (1,2)
and msh.NewMembershipStatus = 'Cancelled'
and year(msh.ChangeDate) = year(getdate())
and month(msh.ChangeDate) = month(getdate())
and day(msh.ChangeDate) = day(getdate())
)
......返回需要1.5分钟。始终如一。
****正在发生什么?我必须使用变量,因为我需要在我的存储过程中稍后对结果求和。我将其他查询的结果存储在同一个proc中,并且它们很快。我很难过。
以下是SLOW查询的执行计划:
以下是FAST查询的执行计划:
我说实话,我不知道这些执行计划的含义或我需要纠正的内容。
答案 0 :(得分:2)
非常奇怪,但尝试这样的事情......
declare @CancellationsToday int;
select @CancellationsToday = count(*)
from MembershipStatusHistory msh
join gym.Account a
on msh.AccountID = a.AccountID
join gym.MembershipType mt
on a.MembershipTypeID = mt.MembershipTypeID
join MemberTypeGroups mtg
on mt.MemberTypeGroupID = mtg.MemberTypeGroupID
where mtg.MemberTypeGroupID IN (1,2)
and msh.NewMembershipStatus = 'Cancelled'
and year(msh.ChangeDate) = year(getdate())
and month(msh.ChangeDate) = month(getdate())
and day(msh.ChangeDate) = day(getdate())
答案 1 :(得分:1)
嗯奇怪,试试这个:
SELECT @CancellationsToday = COUNT(*) FROM ......
值得一提的另一件事是不要在WHERE
子句中使用函数。
我认为您只有msh.ChangeDate
中的日期,请使用今天的日期制作变量:
DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
并在WHERE
子句中使用它。
答案 2 :(得分:0)
您需要查看SQL Server Management Studio中两个查询的执行计划,以了解发生了什么以及为什么。您可以添加一个可以解决问题的索引,或者计划本身可能会告诉您哪些方法以及如何解决问题。没有这些信息,很难知道在这里说些什么。
正如我在上面评论的那样,调整你的where子句以摆脱六个函数调用,只需比较" date"带有常量变量的数据库列的一部分应该有所帮助。
另一个小建议是明确关于INNER JOIN,如果这是你想要的......总是指定你想要的连接类型(INNER JOIN,LEFT OUTER JOIN,CROSS JOIN等)只是加入'。它使事情变得更加清晰。