トリガと一括要求に関するベストプラクティス
よくある開発の落とし穴は、トリガの呼び出しには複数のレコードが含まれないと想定することです。Apex トリガは、一括操作ができるように最適化されています。したがって、開発者は一括操作をサポートするロジックを記述する必要があります。
これは、弱点のあるプログラミングパターンの例です。トリガの呼び出し時に取り込まれるレコードは 1 つのみと想定します。この場合、ほとんどのユーザインターフェースイベントはサポートされますが、SOAP API または Visualforce を使用して呼び出される一括操作はサポートされません。
1trigger MileageTrigger on Mileage__c (before insert, before update) {
2 User c = [SELECT Id FROM User WHERE mileageid__c = Trigger.new[0].id];
3}これは、弱点のあるプログラミングパターンの別の例です。トリガの呼び出し時に、取り込まれるレコードは 100 未満と想定します。要求に 20 を超えるレコードが取り込まれると、トリガは、100 SELECT ステートメントの SOQL クエリの制限を超えます。
1trigger MileageTrigger on Mileage__c (before insert, before update) {
2 for(mileage__c m : Trigger.new){
3 User c = [SELECT Id FROM user WHERE mileageid__c = m.Id];
4 }
5}ガバナ制限についての詳細は、「実行ガバナと制限」を参照してください。
この例では、ガバナ制限を重視し、トリガの一括処理をサポートする適切なパターンを示します。
1Trigger MileageTrigger on Mileage__c (before insert, before update) {
2 Set<ID> ids = Trigger.newMap.keySet();
3 List<User> c = [SELECT Id FROM user WHERE mileageid__c in :ids];
4}このパターンは、Trigger.new コレクションをセットに渡し、単一の SOQL クエリでそのセットを使用して、トリガの一括処理を重視ます。このパターンは、SOQL クエリ数を制限しますが、要求が受信するすべてのレコードを取り込みます。
一括プログラム設計のベストプラクティス
次は、設計パターンのベストプラクティスです。
- コレクションにレコードを追加し、それらのコレクションに対してデータ操作言語 (DML) の操作を実行して、DML の数を最小化します。
- レコードを事前処理してセットを生成することによって、IN 句を使用する 1 つの SOQL ステートメントに配置できる SOQL ステートメント数を最小化します。