捕获结果变量时可怕的sql server性能

时间:2014-07-25 23:58:40

标签: sql sql-server sql-server-2012

我正在使用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查询的执行计划: enter image description here

以下是FAST查询的执行计划: enter image description here

我说实话,我不知道这些执行计划的含义或我需要纠正的内容。

3 个答案:

答案 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等)只是加入'。它使事情变得更加清晰。