Is It Beneficial To Call ExecuteMultipleRequest From Within A Plugin?

耗尽温柔 提交于 2019-12-05 07:57:14

So I did what I should have done before, and just created a plugin to test this. This is running on CRM 2013 on my local VM (Pre-Operation), so results can vary, but I'm seeing plain old Create taking about 290ms less per 100 entities

I first created this plug

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));
    }
}

Registered the plugin and ran 10 tests. Here are the results (ASCII tables, oh yah!):

+------------------+---------------+-------+
| 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 |
+------------------+---------------+-------+

So from these results, there is no need to execute an ExecuteMultipleRequest from within a plugin. You're already on the server, having to execute more code to perform the same operation.

Update 1 - 1000 Creates Test against a full environment

I ran this test again for the creation of a 1000 records, and in a full fledged environment with separate boxes for SQL, Services, and Web. Very similar results (only ran 5 tests since it was taking a lot longer)

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

Interesting thing was the time was around 25 times longer for 10 times more records, but the differences was only 12 times more. ( Attempted to do updates rather than deletes, but I kept on getting timeout errors, even at just one for each... Must have been creating some sort of infinite loop, just not sure what... )

For a 1000 creates, its almost 4 seconds slower. I wouldn't use it in my plugins...

Those type of results fall in line with what I've seen when running tests on an all in one box (i.e. CRM Server, SQL, ... all contained in one machine). When run against a more traditional deployment, I've see those results inverse. Also, the gap widens significantly as more messages are added to your request. Consider increasing your loop to process 300, 500, or 1000 (The default max for ExecuteMultipleRequest) records and run it against a deployment that has separated the CRM Front End, CRM Async, and SQL servers out onto different boxes.

I know this is an old question / answer, but since I found it in my research, I thought I'd also chime in with some information I found on MSDN:

Throttling of concurrent calls – for Microsoft Dynamics 365 (online) there is a limit of 2 concurrent ExecuteMultipleRequest executions per organization. If that limit is exceeded, a Server Busy fault is thrown before the first request is ever executed. For an on-premises deployment, throttling is not enabled by default.

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

Based on this, I would recommend never using ExecuteMultipleRequest in any circumstance except for initial data load scenarios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!