6

我知道当从 CRM 外部执行批量更新时, ExecuteMultipleRequest是一个巨大的性能提升器。我不知道从 CRM 插件中调用它是否有益。

我目前的理解是,使用 ExecuteMultipleRequest 的主要性能增益在于实际的 SOAP 消息传递成本。因此(为了更新 5000 条记录)而不是发送 5000 条单独的 Soap 消息(每个都必须被序列化、验证、传输等),所有这些都必须发送到服务器,您可以只发送一条带有 5000 条记录的消息。但是当从插件调用时,您已经在服务器上,因此不必进行 SOAP 调用,因此使用它没有任何好处。

还有其他一些我没有看到的潜在好处吗?

4

3 回答 3

9

所以我做了我以前应该做的,只是创建了一个插件来测试它。这是在我的本地 VM(预操作)上的 CRM 2013 上运行的,因此结果可能会有所不同,但我看到普通的旧 Create 每 100 个实体减少约 290 毫秒

我首先创建了这个插件

public class ExecuteMultipleTester : PluginBase
{
    protected override void ExecuteInternal(Common.Plugin.LocalPluginContext pluginContext)
    {
        var watch = new Stopwatch();
        var service = pluginContext.OrganizationService;

        watch.Start();
        var request = new ExecuteMultipleRequest
        {
            Settings = new ExecuteMultipleSettings
            {
                ContinueOnError = false,
                ReturnResponses = false,
            },
            Requests = new OrganizationRequestCollection()
        };

        for (var i = 0; i < 100; i++)
        {
            request.Requests.Add(new CreateRequest
            {
                Target = new new_Year
                {
                    new_Year = i + "- B",
                    new_YearIntValue = i,
                }
            });
        }
        service.Execute(request);
        watch.Stop();

        var multipleCreate = watch.ElapsedMilliseconds;

        watch.Restart();
        for(var i = 0; i < 100; i++)
        {
            service.Create(new new_Year
            {
                new_Year = i + "- A",
                new_YearIntValue = i,
            });
        }
        watch.Stop();

        throw new InvalidPluginExecutionException(String.Format("ExecuteMultipleRequest Time was: {0}ms, Standard was: {1}ms", multipleCreate, watch.ElapsedMilliseconds));
    }
}

注册插件并运行 10 次测试。以下是结果(ASCII 表,哦,是的!):

+------------------+---------------+-------+
| Execute Multiple | Sevice.Create | Diff  |
+------------------+---------------+-------+
| 777              | 408           | 369   |
| 493              | 327           | 166   |
| 614              | 346           | 268   |
| 548              | 331           | 217   |
| 577              | 312           | 265   |
| 675              | 313           | 362   |
| 574              | 318           | 256   |
| 553              | 326           | 227   |
| 810              | 318           | 492   |
| 595              | 311           | 284   |
+------------------+---------------+-------+
|                    Average Diff: | 290.6 |
+------------------+---------------+-------+

因此,根据这些结果,无需在插件中执行 ExecuteMultipleRequest。您已经在服务器上,必须执行更多代码才能执行相同的操作。

更新 1 - 1000 针对完整环境创建测试

我再次运行此测试以创建 1000 条记录,并在一个完整的环境中使用单独的 SQL、服务和 Web 框。非常相似的结果(只进行了 5 次测试,因为它需要更长的时间)

+------------------+----------+--------+
| Execute Multiple | Standard |  Diff  |
+------------------+----------+--------+
|            18922 | 15057    | 3865   |
|            18668 | 14946    | 3722   |
|            18162 | 14773    | 3389   |
|            19059 | 14925    | 4134   |
|            18334 | 15306    | 3028   |
+------------------+----------+--------+
|                  | Average  | 3627.6 |
+------------------+----------+--------+

有趣的是,对于 10 倍的记录,时间大约延长了 25 倍,但差异只有 12 倍。(尝试进行更新而不是删除,但我不断收到超时错误,即使每个错误只有一个......一定是在创建某种无限循环,只是不确定是什么......)

对于 1000 次创建,它慢了近 4 秒。我不会在我的插件中使用它...

于 2015-02-09T20:09:13.190 回答
0

这些类型的结果与我在一体机上运行测试时看到的结果一致(即 CRM 服务器、SQL ......全部包含在一台机器中)。当针对更传统的部署运行时,我看到了相反的结果。此外,随着更多消息添加到您的请求中,差距会显着扩大。考虑增加循环以处理 300、500 或 1000(ExecuteMultipleRequest 的默认最大值)记录,并针对将 CRM 前端、CRM 异步和 SQL 服务器分开到不同盒子的部署运行它。

于 2015-02-13T13:38:24.450 回答
0

我知道这是一个老问题/答案,但由于我在研究中发现了它,我想我也会加入我在 MSDN 上找到的一些信息:

并发调用限制 – 对于 Microsoft Dynamics 365(在线),每个组织限制2 个并发ExecuteMultipleRequest 执行。如果超过该限制,则在执行第一个请求之前会引发错误。对于本地部署,默认情况下不启用限制。Server Busy

https://msdn.microsoft.com/en-au/library/jj863631.aspx#limitations

基于此,我建议不要ExecuteMultipleRequest在任何情况下使用,除了初始数据加载场景

于 2017-09-11T01:45:23.757 回答