背景
我有一个单元测试框架,它为我的单元测试创建实体,预先形成测试,然后自动删除实体。在我们的dev环境中,除了一些实体需要15-30秒的时间删除外,它一直运行得很好。
最近,我在Amazon中收到了一个VM设置,以执行一些需要几个发布周期才能完成的长期更改。当我在VM上运行单元测试时,我不断地收到试图删除实体的SQL超时错误。
步骤
我已经完成了一系列的发现/行动步骤:
fn_CollectForCascadeWrapper
上。我的单元测试中只有6个实体,它们被删除时不需要级联删除。在它上运行估计执行计划,并添加它请求的一些索引。这仍然没有解决超时问题。fn_CollectForCascadeWrapper
返回一个结果,这意味着我的单元测试中的6个实体不需要级联。运行单元测试,并再次获得SQL超时错误。根据追踪,实际的delete语句正在超时:delete from [New_inquiryExtensionBase] where ([New_inquiryId] = '7e250a5f-890e-40ae-9d2d-c55bbd7250cd');
delete from [New_inquiryBase]
OUTPUT DELETED.[New_inquiryId], 10012
into SubscriptionTrackingDeletedObject (ObjectId, ObjectTypeCode)
where ([New_inquiryId] = '7e250a5f-890e-40ae-9d2d-c55bbd7250cd')
SubscriptionTrackingDeletedObject
表,注意到其中有2100条记录。删除表中的所有记录,并重新运行我的单元测试。它实际上在正常的15-30秒的时间范围内被删除。SubscriptionTrackingDeletedObject
的用途,以及异步服务对其进行清理。注意到异步服务不在服务器上运行。打开服务,等了10分钟,又问了一遍桌子。我的6个实体还在那里。查看跟踪日志和saw超时错误:Error cleaning up Principal Object Access Table
SELECT COUNT(*)
,7分钟后,它返回了2.61亿记录!研究如何清理表,我发现的唯一东西是角色提升6 (我们目前正在使用11)。接下来是什么?
POA会不会影响删除?还是仅仅是影响异步服务的POA影响了删除?插入到SubscriptionTrackingDeletedObject
中真的会导致我的问题吗?
发布于 2013-10-04 14:24:57
最后,我打开了Server分析,并运行了问题中列出的delete语句。执行了3.5分钟。我以为它会把其他东西从POA的桌子上踢下来,但是不,它只是删除了那些记录。
我再次查看了查询执行计划,并注意到有许多嵌套循环:
它正在查看包含引用的子表(请参见树结构中的13个小分支插入到底部,对吗?)因此,所有的读取都是在索引本身上执行的,并且需要花费很长时间才能加载到我的uber慢速VM上。
最后,我对一个不同的id运行相同的查询,它在2秒内运行。然后我尝试了我的单元测试,最后它成功地完成了。
我猜每次我尝试删除时,都会启动一个事务,然后CRM上的超时会回滚事务,永远不允许加载子实体索引。因此,我当前的修复方法是确保在实际执行delete之前将子索引加载到内存中。如何做到这一点,我不确定(对每个子实体执行一个id查询?)。
编辑
我们有一位来自微软的性能分析师出来,他们写了一份长达200多页的报告。98%的人认为POA表太长。圣诞节期间,我们关闭了CRM,运行了一些脚本来清理POA表。这是非常有用的。
https://stackoverflow.com/questions/19162534
复制相似问题