从插件中调用ExecuteMultipleRequest是否有益?

时间:2015-02-09 16:40:42

标签: dynamics-crm-2011 dynamics-crm-2013 dynamics-crm-2015

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

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

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

3 个答案:

答案 0 :(得分:9)

所以我做了之前应该做的事情,并且刚刚创建了一个插件来测试它。这是在我的本地虚拟机(运营前)上的CRM 2013上运行,因此结果会有所不同,但我看到普通的创建每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秒。我不会在我的插件中使用它......

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我知道这是一个古老的问题/答案,但自从我在研究中发现它以来,我想我也会在MSDN上找到一些信息:

  

并发调用的限制 - 适用于Microsoft Dynamics 365(在线)   存在 2并发 ExecuteMultipleRequest执行 per的限制   组织即可。如果超出该限制,则会出现Server Busy错误   在执行第一个请求之前抛出。对于内部部署   部署,默认情况下不启用限制。

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

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