The Dangers of Guid.NewGuid();


Microsoft Dynamics CRM uses GUIDs as their primary key for the entity’s SQL table.  Using GUIDs as a primary key is usually not the best item due the random sequence of numbers and letters.  The Dynamics platform has an algorithm that generates GUIDs in sequential order.  This special GUID enables the SQL Server to index the entity table more efficiently, so that records can be retrieved more quickly.

The Microsoft Dynamics CRM SDK Best practices for developing with Microsoft Dynamics CRM, states, Allow the system to automatically assign the GUID (Id) for you instead of manually creating it yourself. This suggestion allows Microsoft Dynamics CRM to take advantage of sequential GUIDs, which provide better SQL performance. The following sample code shows how to call the Create method to obtain a system-assigned GUID.

I have seen a number of times where a customer has created a plugin or an application that needs to create records in CRM using the SDK and they populate the record’s ID with GUID generated using with System.Guid’s NewGuid method.  The System.Guid’s GUID does not generate a sequential GUID that conforms  to the CRM platform’s GUID pattern.

AccountIDs

As you can see, the AccountID in rows 15 through 23 are generated by the platform and 24 through 34 are generated using the NewGuid method.

If you have to create records programmatically you should always let the platform create the record an ID and if you need to use the ID later, create a variable ready to assign the ID to.

Guid newAccount;

using (OrganizationServiceProxy organizatonProxy =
     GetProxy<IOrganizationService, OrganizationServiceProxy>(orgServiceManagement, 
     GetCredentials(authtype)))
{
     Entity account = new Entity("account");
     account.Attributes.Add("name", name);

     newAccount = organizatonProxy.Create(account);
}

Now there might be times that you might need to generate your own CRM primary keys, such as a data import of related records.  David Browne authored a blog post, http://blogs.msdn.com/b/dbrowne/archive/2012/07/03/how-to-generate-sequential-guids-for-sql-server-in-net.aspx, that has sample code on generating sequential GUIDs.  Generating your own primary ID’s should be done in rare occasions.

Thanks,
Walter

Microsoft Premier Field Engineer

MSFT Logo

Comments (3)

  1. İsmail Tutumluer says:

    Thanks.

  2. Erik van Hoof says:

    What kind of performance impact can we expect and where will it be mostly visible?

    1. Any performance impact is necessarily specific to each implementation, but the more significant impact would be on record creation, not on retrieval. CRM creates a clustered index on the primary key of each entity; if a new record has a sequential guid, then it will be added onto the end on the clustered index, so no index fragmentation will occur. However, if the new record does not have a sequential guid, it will need to be inserted within the index. If the index is full (fillfactor = 100%), then this will cause page splits and fragmentation, whereas if you have some space in the index (e.g. fillfactor ~90%), then the impact is not so significant.

      If you are importing data in bulk, and there’s no space in the index, then the cumulative overhead may be noticeable. If you were doing this frequently, and you have CRM OnPremise, I’d recommend setting an appropriate fillfactor so that page splitting is unlikely to occur, and reorganising the clustered index before and after the import. As a worst case, if you’re importing in bulk, and running multiple imports on the same entity in parallel, you may also get noticeable locking issues (either slowing performance, or possibly deadlocks)

      Once indexes are rebuilt or reorganised after the update, there will be no ongoing overhead

Skip to main content