微软动态CRM专家罗勇 ,回复311或者20190311可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me 。

本文主要是根据微软官方2018年4月17日更新的知识文章 Performance is slow if the AsyncOperationBase table becomes too large in Microsoft Dynamics CRM 而写,原文是英文的,我就摘取其部分内容,加入自己的理解简述下,更加具体的请参考原文。本人不对参考本文后执行的操作而导致的任何后果承担任何责任或者连带责任,且看,且珍惜。

倘若这个表记录太多,比如过千万条,很可能影响整个Dynamics 365 Customer Engagement的性能,为了快速删除,这里提供了SQL进行删除的方法,对于Dynamics 365 Customer Engagement 本地部署版本(On-Premise),自己根据这个知识文章进行操作就可以,若是Dynamics 365 Customer Engagement Online,可以开个Case给微软客户服务技术支持中心请他们来执行。当然啦,你还可以自己写个程序,其多个线程来利用ExecuteMultipleRequest消息删除这个实体中的记录。

这里讲一下SQL删除的方法,这个方法比自己写程序调用消息来删除要快很多。

执行前的准备工作:

1. 先执行如下的T-SQL脚本添加索引。

  1. CREATE NONCLUSTERED INDEX CRM_WorkflowLog_AsyncOperationID ON [dbo].[WorkflowLogBase] ([AsyncOperationID])
  2. GO
  3.  
  4. CREATE NONCLUSTERED INDEX CRM_DuplicateRecord_AsyncOperationID ON [dbo].[DuplicateRecordBase] ([AsyncOperationID])
  5. GO
  6.  
  7. CREATE NONCLUSTERED INDEX CRM_BulkDeleteOperation_AsyncOperationID ON [dbo].[BulkDeleteOperationBase]
  8. (AsyncOperationID)
  9. GO

2.停止名称为 Microsoft Dynamics 365 异步处理服务 (英文名称为Microsoft Dynamics CRM Asynchronous Processing Service)的异步服务,非必须。

3.如果可能更改数据库的恢复模式(Recovery model)为简单(Simple),这样能减少写入的数据库日志。右击数据库,选择属性,更改如下:生产环境不要做这个步骤

然后就到了真正执行的时候了,执行如下的T-SQL脚本:

  1. IF EXISTS (SELECT name from sys.indexes
  2. WHERE name = N'CRM_AsyncOperation_CleanupCompleted')
  3. DROP Index AsyncOperationBase.CRM_AsyncOperation_CleanupCompleted
  4. GO
  5. CREATE NONCLUSTERED INDEX CRM_AsyncOperation_CleanupCompleted
  6. ON [dbo].[AsyncOperationBase] ([StatusCode],[StateCode],[OperationType])
  7. GO
  8.  
  9. while(1=1)
  10. begin
  11. declare @DeleteRowCount int = 10000
  12. declare @rowsAffected int
  13. declare @DeletedAsyncRowsTable table (AsyncOperationId uniqueidentifier not null primary key)
  14. insert into @DeletedAsyncRowsTable(AsyncOperationId)
  15. Select top (@DeleteRowCount) AsyncOperationId from AsyncOperationBase
  16. where
  17. OperationType in (1, 9, 12, 25, 27, 10)
  18. AND StateCode = 3
  19. AND StatusCode in (30, 32)
  20.  
  21. select @rowsAffected = @@rowcount
  22. delete poa from PrincipalObjectAccess poa
  23. join WorkflowLogBase wlb on
  24. poa.ObjectId = wlb.WorkflowLogId
  25. join @DeletedAsyncRowsTable dart on
  26. wlb.AsyncOperationId = dart.AsyncOperationId
  27. delete WorkflowLogBase from WorkflowLogBase W, @DeletedAsyncRowsTable d
  28. where
  29. W.AsyncOperationId = d.AsyncOperationId
  30. delete BulkDeleteFailureBase From BulkDeleteFailureBase B, @DeletedAsyncRowsTable d
  31. where
  32. B.AsyncOperationId = d.AsyncOperationId
  33. delete BulkDeleteOperationBase From BulkDeleteOperationBase O, @DeletedAsyncRowsTable d
  34. where
  35. O.AsyncOperationId = d.AsyncOperationId
  36. delete WorkflowWaitSubscriptionBase from WorkflowWaitSubscriptionBase WS, @DeletedAsyncRowsTable d
  37. where
  38. WS.AsyncOperationId = d.AsyncOperationID
  39. delete AsyncOperationBase From AsyncOperationBase A, @DeletedAsyncRowsTable d
  40. where
  41. A.AsyncOperationId = d.AsyncOperationId
  42. /*If not calling from a SQL job, use the WAITFOR DELAY*/
  43. if(@DeleteRowCount > @rowsAffected)
  44. return
  45. else
  46. WAITFOR DELAY '00:00:02.000'
  47. end

说明:Opertaion Type的说明如下:

  • Workflow Expansion Task (1)
  • Collect SQM data (9)
  • PersistMatchCode (12)
  • FullTextCatalogIndex (25)
  • UpdateContractStates (27)
  • Workflow (10)

执行完毕后,也有些收尾工作,如下:

1. 建议删除之前临时增加的索引(原文未提到此步骤,我的建议是恢复原状):

  1. Drop INDEX dbo.WorkflowLogBase.CRM_WorkflowLog_AsyncOperationID;
  2. GO
  3.  
  4. Drop INDEX dbo.DuplicateRecordBase.CRM_DuplicateRecord_AsyncOperationID;
  5. GO
  6.  
  7. Drop INDEX dbo.BulkDeleteOperationBase.CRM_BulkDeleteOperation_AsyncOperationID;
  8. GO

2. 使用T-SQL更新下表的统计信息:

  1. UPDATE STATISTICS [dbo].[AsyncOperationBase] WITH FULLSCAN
  2. UPDATE STATISTICS [dbo].[DuplicateRecordBase] WITH FULLSCAN
  3. UPDATE STATISTICS [dbo].[BulkDeleteOperationBase] WITH FULLSCAN
  4. --下面这个表在Dynamcis 365 Customer Engagement中不存在
  5. --UPDATE STATISTICS [dbo].[WorkflowCompletedScopeBase] WITH FULLSCAN
  6. UPDATE STATISTICS [dbo].[WorkflowLogBase] WITH FULLSCAN
  7. UPDATE STATISTICS [dbo].[WorkflowWaitSubscriptionBase] WITH FULLSCAN

 3. 若有更改数据库的恢复模式,请恢复原状。

值得提醒大家注意的是,部署到生产环境的工作流应该选择 【自动删除已完成的工作流作业(以节省磁盘空间)】,部署到生产环境的SDK插件步骤要选择【Delete AsyncOperation if StatusCode = Successful】。当然啦,也没有必要一个个手工去看,我自己写了个工具可以检查出来没有选择的,请参考我的文章:Dynamics 365检查工作流、SDK插件步骤是否选中运行成功后自动删除系统作业记录

Dynamics 365 CE中AsyncOperationBase表记录太多,影响系统性能怎么办?的更多相关文章

  1. Dynamics 365 CE中使用FetchXML进行聚合运算

    微软动态CRM专家罗勇 ,回复328或者20190429可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me! Dynamics 365 Customer Engagement ...

  2. Dynamics 365 CE Update消息PostOperation阶段Image的尝试

    我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...

  3. Dynamics 365 marketing中添加自定义渠道磁贴

    Dynamics 365 marketing中默认的渠道只有Marketing Email和Marketing Activity,想要添加其他渠道必须自定义磁贴,自定义磁贴的步骤如下: 1.创建实体 ...

  4. 使用Dynamics 365 CE Web API查询数据加点料及选项集字段常用查询

    微软动态CRM专家罗勇 ,回复336或者20190516可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me. 紧接上文:配置Postman通过OAuth 2 implicit ...

  5. Use SQL to Query Data from CDS and Dynamics 365 CE

    from : https://powerobjects.com/2020/05/20/use-sql-to-query-data-from-cds-and-dynamics-365-ce/ Have ...

  6. Dynamics 365 CE命令栏按钮点击后刷新表单页面方法

    微软动态CRM专家罗勇 ,回复326或者20190428可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me! Dynamics 365 Customer Engagement ...

  7. Dynamics 365 CE将自定义工作流活动程序集注册到磁盘并引用其他类库

    我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...

  8. 安装完成Dynamics 365 CE后别忘了更改维护作业的运行时间

    摘要: 微软动态CRM专家罗勇 ,回复309或者20190308可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 安装完毕Dy ...

  9. 做了面向互联网部署的Dynamics 365 CE更改AD FS的登录页面

    摘要: 微软动态CRM专家罗勇 ,回复306或者20190307可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 默认情况下A ...

随机推荐

  1. js 格式化数字,格式化金额:

    js 格式化数字,格式化金额: function number_format(number, decimals, dec_point, thousands_sep) { /* * 参数说明: * nu ...

  2. 【javascript】函数中的this的四种绑定形式 — 大家准备好瓜子,我要讲故事啦~~

       javascript中的this和函数息息相关,所以今天,我就给大家详细地讲述一番:javascript函数中的this   一谈到this,很多让人晕晕乎乎的抽象概念就跑出来了,这里我就只说最 ...

  3. [Swift]LeetCode14. 最长公共前缀 | Longest Common Prefix

    Write a function to find the longest common prefix string amongst an array of strings. If there is n ...

  4. [Swift]LeetCode19. 删除链表的倒数第N个节点 | Remove Nth Node From End of List

    Given a linked list, remove the n-th node from the end of list and return its head. Example: Given l ...

  5. [Swift]LeetCode736. Lisp 语法解析 | Parse Lisp Expression

    You are given a string expressionrepresenting a Lisp-like expression to return the integer value of. ...

  6. Docker 搭建pxc集群 + haproxy + keepalived 高可用(二)

    上一节我们有了两个分片的pxc集群,这一节我们接着安装haproxy和keepalived的实现集群的高可用 一.先下载haproxy的镜像 [root@localhost ~]# docker pu ...

  7. Unable to preventDefault inside passive event listener due to target being treated as passive

    Unable to preventDefault inside passive event listener due to target being treated as passive 今天在做项目 ...

  8. 使用google搜索时的10个小技巧!

    为大家分享一些google的技巧,很多工作了好几年的同学还不知道如何高效的利用这些技巧,希望同学们掌握!此为google的技巧,百度现在也基本上都实现了这些功能.   使用搜索引擎的10个搜索技巧   ...

  9. 使用xUnit为.net core程序进行单元测试 -- Assert

    第一部分: http://www.cnblogs.com/cgzl/p/8283610.html Assert Assert做什么?Assert基于代码的返回值.对象的最终状态.事件是否发生等情况来评 ...

  10. DataRead和DataSet的异同

    第一种解释 DataReader和DataSet最大的区别在于,DataReader使用时始终占用SqlConnection(俗称:非断开式连接),在线操作数据库时,任何对SqlConnection的 ...