Guid.NewGuid(); 使用時の注意点

 

みなさん、こんにちは。

今回は Microsoft Dynamics CRM 開発に関するトピックを紹介します。この記事は以下のブログの紹介です。

The Dangers of Guid.NewGuid();
https://blogs.msdn.com/b/crminthefield/archive/2015/01/19/the-dangers-of-guid-newguid.aspx

背景と概要 Microsoft Dynamics CRM は GUID をエンティティのプライマリキーとして使用します。GUID をプライマリキーとして使用する事は、ランダムな数字と文字列がプライマリキーとして使用される為、SQL Server の観点からベストプラクティスではありません。しかし、Dynamics CRM プラットフォームは GUID を連続な順番で生成する機能があります。

SQL Server のインデックス管理
SQL Server のインデックスはキーデータが指定された並び順(昇順・降順)で保存されています。GUID はランダムな数字と文字列の組み合わせなので、キーとして使用される場合、格納されているキーデータの間に新規データが追加される場面が発生します。SQL Server はこのような場合、ページを分割します。ページ分割は、ページ分割自体が手数がかかる処理であると同時に、ページ内のデータ個数の低下、インデックスページがデータファイル内で連続しなくなる断片化という、パフォーマンス面で考慮するべき幾つかの挙動が伴います。このような側面から、GUID のようなランダムな文字列をプライマリキーとして使用するのは、SQL Server の観点からベストプラクティスではありません。

Dynamics CRM の 連続した GUID 生成機能
Dynamics CRM プラットフォームは GUID を連続な順番で生成するアルゴリズムを持っています。 キーとして使用される GUID が連続しているので、常にインデックスの最後に新規データが追加されます。 この為、新規データ作成時にページ分割は発生しません。これにより、SQL Server がエンティティテーブルを効率的にインデックスする事を可能にします。結果、レコード取得を速める効果を期待できます。

GUID の生成方法
Microsoft Dynamics CRM SDK の「Microsoft Dynamics CRM での開発におけるベスト プラクティス」で「システムによる GUID の作成の使用」が紹介されています。 この方法を行うことで Dynamics CRM が連続した GUID を使用できるようになり、パフォーマンス面の効果が期待できます。この記事の後で紹介するサンプルコードで、「Create」メソッドでシステムが割り当てた GUID を使用する方法を説明します。

カスタムプラグインやアプリケーションで、CRM  SDK を使用してレコードを作成する要件は沢山あります。GUID の生成に System.GUID の NewGuid メソッドが使用されている事をしばしば見る事があります。System.GUID は CRM プラットフォームが使用する連続した GUID パターンの GUID は生成しません。
以下の画像の AccountID 15 行目から 23 行目は Dynamics CRM プラットフォームが作成したものです。 24 行目から 34 行目は NewGuid によって生成されたものです。このように、NewGuid は CRM プラットフォームが生成する GUID パターンと異なる GUID を生成します。

5824_AccountIDs_1890FDEA

サンプルコード
プログラム内で、作成したレコードの ID を後処理で利用する必要がある場合は、Dynamics CRM プラットフォームがレコード作成後に返す ID を使用するようにします。

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

データインポート時に関連レコードのプライマリキーを生成する場面など、自分で CRM のプライマリキーを生成する必要がある場面があります。そのような場合は、David Browne が投稿した記事に連続した GUID を生成するサンプルコードがありますので、参考にしてみて下さい。

How to Generate Sequential GUIDs for SQL Server in .NET
https://blogs.msdn.com/b/dbrowne/archive/2012/07/03/how-to-generate-sequential-guids-for-sql-server-in-net.aspx

まとめ
Dynamics CRM にレコードを作成する場合は、自分でGUID を生成するのではなく、なるべく Dynamics CRM プラットフォームに生成させて下さい。自分で生成した場合は、パフォーマンス面で不利な影響がある場合があります。

 

- Kensuke Kitazawa