永不停止SQL Server 2012中的查询

时间:2015-07-21 09:20:38

标签: sql-server amazon-web-services sql-server-2012

SQL Server 2012,Amazon RDS

这是我的简单查询

update [dbo].[DeliveryPlan] 
set [Amount] = dp.Amount + 
                  case when @useAmountColumn = 1 and dbo.ConvertToInt(bs.Amount) > 0 
                         then dbo.ConvertToInt(bs.Amount) 
                         else @amount 
                  end
from
    BaseSpecification bs
join 
    BaseSpecificationStatusType t on (StatusTypeID = t.StatusTypeID)
join 
    [DeliveryPlan] dp on (dp.BaseSpecificationID = bs.BaseSpecificationID and dp.ItemID = @itemID)
where 
     bs.BaseID = 130 and t.IsActive = 1

它无法完成。如果条件bs.BaseID = 130(更新7000行)更改为bs.BaseID = 3(更新1000000行),则持续13秒。

统计是实际的,我认为

在性能监视器中,我看到5%的处理器使用率

当我使用sp观察活动连接和此查询时 tempdb_allocations是32,tembdb_current - 32,读取 - 32 000 000,cpu - 860 000(查询持续20分钟)

有什么问题?

更新:我为[DeliveryPlan]添加了非聚集索引 - BaseSpecificationID + ItemID,问题就消失了。不幸的是,我每天都会遇到不同的问题。而且问题不可预测地消失了。

3 个答案:

答案 0 :(得分:0)

您的基表可能会遇到锁定状态。

优化您的查询以直接更新dp,以避免更新DeliveryPlan的所有行

update dp set [Amount] = dp.Amount + 
    case 
        when @useAmountColumn=1 and dbo.ConvertToInt(bs.Amount)>0 then 
            dbo.ConvertToInt(bs.Amount) 
        else @amount 
    end
from 
    BaseSpecification bs 
    join BaseSpecificationStatusType t on (bs.StatusTypeID = t.StatusTypeID) 
    join [DeliveryPlan] dp on (dp.BaseSpecificationID = bs.BaseSpecificationID)
where 
    bs.BaseID = 130 
    and t.IsActive = 1
    and dp.ItemID = @itemID

答案 1 :(得分:0)

这将以更好的方式执行,因为连接条件将缩小第一个go本身的行数,而不是等待where子句执行。两者的执行计划都不同(在哪里/不在哪里)。

UPDATE dp
  SET Amount = dp.Amount + CASE
                       WHEN @useAmountColumn = 1
                        AND dbo.ConvertToInt( bs.Amount ) > 0 THEN dbo.ConvertToInt( bs.Amount )
                           ELSE @amount
                       END
  FROM BaseSpecification bs
   JOIN BaseSpecificationStatusType t ON
                                        ( bs.StatusTypeID = t.StatusTypeID
                                      AND bs.BaseID = 130
                                      AND t.IsActive = 1
                                        )
   JOIN DeliveryPlan dp ON
                          ( dp.BaseSpecificationID = bs.BaseSpecificationID
                        AND dp.ItemID = @itemID
                          );

答案 2 :(得分:0)

如果更新部分中提到的问题是它随机出现,那听起来就像是参数嗅探不好。当问题发生时,您可以查看计划缓存以检查查询计划是否正常,如果没有,计划创建的值是什么(您可以在计划中最左边的对象中找到它们)以及示例使用sp_recompile,看看下次会有什么样的计划。

相关问题