我有一个单元测试框架,可以为我的单元测试创建实体,预先测试,然后自动删除实体。它一直工作得很好,只是有些实体在我们的开发环境中需要15-30秒才能删除。
我最近在Amazon Cloud中收到了一个虚拟机设置来执行一些长期更改,需要完成几个发布周期。当我在VM上运行单元测试时,我不断尝试删除实体的SQL Timeout Errors。
我已经完成了这套发现/行动步骤:
fn_CollectForCascadeWrapper
上发生超时,用于处理级联删除。我的单元测试中只有6个实体,它们被删除的方式不需要级联删除。 Ran估计执行计划,并添加了一些它所请求的索引。这仍然无法解决超时问题。fn_CollectForCascadeWrapper
以返回结果,这意味着我的单元测试中的6个实体不需要级联。完成单元测试并再次获得SQL超时错误。根据跟踪,实际删除声明超时: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
的用途,以及异步服务清理它。注意到Async Service未在服务器上运行。打开服务,等了10分钟再次查询了桌子。我的6个实体仍然在那里列出。查看跟踪日志并查看超时错误:Error cleaning up Principal Object Access Table
SELECT COUNT(*)
,7分钟后它返回了 2.61亿记录!研究了如何清理表格,我发现的唯一内容是for Role Up 6(我们目前正在11日)。 POA会影响删除吗?或者只是影响正在影响删除的异步服务的POA?插入SubscriptionTrackingDeletedObject
真的会导致我的问题吗?
答案 0 :(得分:2)
我最终启用了SQL Server性能分析,并运行了我的问题中列出的删除语句。执行需要3.5分钟。我期待它能够在POA表中踢出其他东西,但是不,它只是删除那些记录。
我再次查看了查询执行计划,发现有很多嵌套循环:
正在查看包含对它的引用的子表(请参阅右下角的树结构插入中的13个小分支?)。因此,所有的读取都是在索引本身上执行的,并且永远需要加载到我的超级慢速VM上。
我最终为不同的id运行相同的查询,并在2秒内运行。然后我尝试了我的单元测试,最后它成功完成了。
我猜每次尝试删除时,都会启动一个事务,然后CRM的超时回滚事务,永远不会允许子实体索引加载。所以我目前的修复是确保在实际执行删除之前将子索引加载到内存中。我将如何做到这一点,我不确定(通过id为每个子实体执行查询?)。
我们有一位来自微软的性能分析师出来,他们写了一篇超过200页的报告。 98%的人表示POA表太长了。 Over Christmas we ended up turning off CRM and running some scripts to cleanup the POA table。这非常有帮助。