如果 Microsoft Dynamics CRM 中的 AsyncOperationBase 表变得太大,性能会变慢
原文
Symptoms
当您运行 Microsoft Dynamics CRM 4.0、Microsoft Dynamics CRM 2011、Microsoft Dynamics CRM 2013 或 Microsoft Dynamics CRM 2015 时,AsyncOperationBase 表会变得非常大。当表包含数百万条记录时,性能会很慢。
此外,类似于以下内容的错误将记录在运行 Microsoft Dynamics CRM 的服务器上的应用程序事件日志中:
Event Type: Error
Event Source: MSCRMDeletionService
Event Category: None
Event ID: 16387
Date: 2009/01/26
Time: 11:41:54 AM
User: N/A
Computer: CRMSERVER
Description: Error: Deletion Service failed to clean up table=CleanupInactiveWorkflowAssembliesProcedure For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
Resolution
若要解决此问题,请通过对
警告 在清理数据之前,请注意,已完成的系统作业在某些情况下具有业务价值,并且必须长期存储。因此,您应该先与组织的管理人员讨论这个问题。
受影响的系统作业:
- SQM 数据收集。Software Quality Metrics 为客户体验计划收集数据。
- 更新合同状态 SQL 作业。此作业每天午夜运行一次。此作业将过期的合同设置为 Expired 状态。
- 组织全文目录索引。在 db 中填充全文索引,以便在 CRM 中搜索 Microsoft 知识库文章。
如果定期作业已取消,则它们将被删除。
Notes 笔记
-
对于 Microsoft Dynamics CRM:本知识库文章中的 SQL 脚本只是一次性的。您可以将其添加为 SQL 作业,以便在夜间、每周或每月重复运行。随着 CRM 的运行,您必须每周应用本文(具体取决于您的业务需求),或者通过编写自定义 BULK DELETE 作业来应用解决方案。(请参阅我们的 CRM SDK 文档,了解 BulkDeleteRequest.QuerySet 属性、BulkDeleteRequest 类和删除顺序)
-
确保从 WorkflowLogBase 对象中删除工作流的 AsyncOperation 记录和相应的记录。
-
确保删除所有相应的 bulkdeletefailure 和 bulkdeleteoperation 记录。
-
如果类型的状态码为 3,且类型的状态码为 30 或 32,请确保仅删除以下 Async 操作类型:
- Workflow Expansion Task (1)
- Collect SQM data (9)
- PersistMatchCode (12)
- FullTextCatalogIndex (25)
- UpdateContractStates (27)
- Workflow (10)
IF EXISTS (SELECT name from sys.indexes WHERE name = N'CRM_AsyncOperation_CleanupCompleted') DROP Index AsyncOperationBase.CRM_AsyncOperation_CleanupCompleted GO CREATE NONCLUSTERED INDEX CRM_AsyncOperation_CleanupCompleted ON [dbo].[AsyncOperationBase] ([StatusCode],[StateCode],[OperationType]) GO while(1=1) begin declare @DeleteRowCount int = 10000 declare @rowsAffected int declare @DeletedAsyncRowsTable table (AsyncOperationId uniqueidentifier not null primary key) insert into @DeletedAsyncRowsTable(AsyncOperationId) Select top (@DeleteRowCount) AsyncOperationId from AsyncOperationBase where OperationType in (1, 9, 12, 25, 27, 10) AND StateCode = 3 AND StatusCode in (30, 32) select @rowsAffected = @@rowcount delete poa from PrincipalObjectAccess poa join WorkflowLogBase wlb on poa.ObjectId = wlb.WorkflowLogId join @DeletedAsyncRowsTable dart on wlb.AsyncOperationId = dart.AsyncOperationId delete WorkflowLogBase from WorkflowLogBase W, @DeletedAsyncRowsTable d where W.AsyncOperationId = d.AsyncOperationId delete BulkDeleteFailureBase From BulkDeleteFailureBase B, @DeletedAsyncRowsTable d where B.AsyncOperationId = d.AsyncOperationId delete BulkDeleteOperationBase From BulkDeleteOperationBase O, @DeletedAsyncRowsTable d where O.AsyncOperationId = d.AsyncOperationId delete WorkflowWaitSubscriptionBase from WorkflowWaitSubscriptionBase WS, @DeletedAsyncRowsTable d where WS.AsyncOperationId = d.AsyncOperationID delete AsyncOperationBase From AsyncOperationBase A, @DeletedAsyncRowsTable d where A.AsyncOperationId = d.AsyncOperationId /*If not calling from a SQL job, use the WAITFOR DELAY*/ if(@DeleteRowCount > @rowsAffected) return else WAITFOR DELAY '00:00:02.000' end
提高删除脚本的性能
-
要提高 Microsoft Dynamics CRM 的整体性能,请将 Microsoft Dynamics CRM 删除服务安排在 Microsoft Dynamics CRM 的非高峰时段运行。默认情况下,该服务在安装 Microsoft Dynamics CRM 时运行。但是,您可以将服务设置为在晚上 10:00 运行,而不是在默认时间运行。为此,请使用 Microsoft Dynamics CRM ScaleGroup 作业编辑器。有关更多信息,请访问下面的 CodePlex 网站:
http://crmjobeditor.codeplex.com/Notes
- 此操作不会直接影响脚本的性能。
- Microsoft Dynamics CRM 4.0 的作业编辑器已弃用,不再可用。
-
为了提高本文中删除脚本的性能,并改进运行类似删除的 Dynamics CRM Deletion Service 代码Microsoft,请在运行本文中的删除脚本之前,将以下三个索引添加到 OrganizationName_MSCRM 数据库中:
CREATE NONCLUSTERED INDEX CRM_WorkflowLog_AsyncOperationID ON [dbo].[WorkflowLogBase] ([AsyncOperationID]) GO CREATE NONCLUSTERED INDEX CRM_DuplicateRecord_AsyncOperationID ON [dbo].[DuplicateRecordBase] ([AsyncOperationID]) GO CREATE NONCLUSTERED INDEX CRM_BulkDeleteOperation_AsyncOperationID ON [dbo].[BulkDeleteOperationBase] (AsyncOperationID) GO
注意 如果您不添加这些索引,则删除脚本可能需要数小时才能运行。
-
在运行此脚本时停止 Microsoft Dynamics CRM 异步处理服务。
-
可选:重新构建以下索引并更新统计信息:
-- Rebuild Indexes & Update Statistics on AsyncOperationBase Table ALTER INDEX ALL ON AsyncOperationBase REBUILD WITH (FILLFACTOR = 80, ONLINE = OFF,SORT_IN_TEMPDB = ON, STATISTICS_NORECOMPUTE = OFF) GO -- Rebuild Indexes & Update Statistics on WorkflowLogBase Table ALTER INDEX ALL ON WorkflowLogBase REBUILD WITH (FILLFACTOR = 80, ONLINE = OFF,SORT_IN_TEMPDB = ON, STATISTICS_NORECOMPUTE = OFF) GO
-
使用以下命令(最好在非高峰时段)对涉及此查询的所有表进行可选 Update Statistics with Full Scan:
UPDATE STATISTICS [dbo].[AsyncOperationBase] WITH FULLSCAN UPDATE STATISTICS [dbo].[DuplicateRecordBase] WITH FULLSCAN UPDATE STATISTICS [dbo].[BulkDeleteOperationBase] WITH FULLSCAN UPDATE STATISTICS [dbo].[WorkflowCompletedScopeBase] WITH FULLSCAN UPDATE STATISTICS [dbo].[WorkflowLogBase] WITH FULLSCAN UPDATE STATISTICS [dbo].[WorkflowWaitSubscriptionBase] WITH FULLSCAN
-
可选:将 MSCRM 数据库的恢复模式更改为 Simple,以避免过多生成 Microsoft SQL Server 日志。对于 SQL Server 2005,请以管理员身份登录到 Microsoft SQL Server Management Studio,右键单击 <org_name>_MSCRM 数据库,依次单击“属性”、“选项”和“恢复模式”。标记 Simple,然后单击 OK。首次运行此脚本后,应将 <org_name>_MSCRM 数据库恢复模式切换回 FULL,以获得最佳数据可恢复性模型。
-
为了提高脚本的性能,可以将 @DeleteRowCount 值 10,000 减小
要确定本文中的脚本要删除的记录数,请对 OrganizationName_MSCRM 数据库运行以下 count 脚本:
Select Count(AsyncOperationId)from AsyncOperationBase WITH (NOLOCK)
where OperationType in (1, 9, 12, 25, 27, 10)
AND StateCode = 3 AND StatusCode IN (30,32)
Script error 脚本错误
当您运行清理脚本时,您可能会收到类似于以下内容的错误消息:
DELETE 语句与 REFERENCE 约束 “asyncoperation_workflowwaitsubscription” 冲突。冲突发生在数据库 “Contoso_MSCRM” 的表 “dbo.WorkflowWaitSubscriptionBase“,列 'AsyncOperationId'。该语句已终止。
如果您收到此错误消息,请停止清理脚本,然后按照以下步骤删除已完成或已取消的工作流存在的剩余 WorkflowWaitSubscription 记录。这些记录应该不再存在,因为它们应该在工作流完成或取消时被删除。您不应看到此查询返回的任何记录。此查询中显示的 WorkflowWaitSubscriptionBase 表中留下的任何内容都是孤立记录。您无法通过 UI 删除这些记录,因为 Microsoft CRM 异步流程处于已取消或已完成状态。
以下脚本将验证已完成和已取消的工作流记录存在多少个孤立的 WorkflowWaitSubscriptionBase 记录:
select count(*) from workflowwaitsubscriptionbase WITH (NOLOCK)
where asyncoperationid in
(Select asyncoperationid from AsyncOperationBase WITH (NOLOCK)
where OperationType in (1, 9, 12, 25, 27, 10)
AND StateCode = 3 AND StatusCode IN (30,32))
以下脚本将删除已完成和已取消的工作流记录的搁浅 WorkflowWaitSubscriptionBase 记录的 WorkflowWaitSubscriptionBase 记录:
delete from workflowwaitsubscriptionbase
where asyncoperationid in(Select asyncoperationidfrom AsyncOperationBase
where OperationType in (1, 9, 12, 25, 27, 10)
AND StateCode = 3 AND StatusCode IN (30,32))
执行此 delete 语句后,AsyncoperationBase 和 Workflow 清理脚本将成功完成。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)