Loading
Salesforce から送信されるメールは、承認済ドメインからのみとなります続きを読む

「Apex CPU 時間の制限を超えました」を回避するためのより効率的なコーディング

公開日: Oct 13, 2022
説明

Salesforce の Apex CPU 時間制限を回避するための効率的なコーディング方法について詳しく説明します。データベース操作や非同期処理を活用し、CPU 時間を節約する方法を具体例とともに紹介します。例えば、マップベースクエリの使用や集計 SOQL の活用、非同期処理の実行などが挙げられます。これにより、トランザクションのタイムアウトを防ぎ、システムのパフォーマンスを向上させることができます。

解決策

アプリケーションサーバ CPU を使用するイベントのみをカウントしています。アプリケーションサーバ CPU を使用してもカウントしないケースもあります。プログラマが制御できないものは含まれません。たとえば、データベースでレコードを検索するのに費やされる時間はカウントされません。コールアウトが戻るのを待つ時間もカウントされません。コードのコンパイルが必要なタイミングも制御できませんのでカウントされません。
 

宣言的なアクションを含めて、アプリケーションサーバで発生するほとんどの処理はカウントされます。コード内の DML が数式を含む入力規則に遭遇した場合は、その式を評価するために費やされた時間がカウントされます。Salesforce アプリケーションサーバ上の 1 つの Apex トランザクションで発生するすべての処理 (実行中の Apex コードと、このコードから呼び出されるパッケージコードやワークフローなどのプロセス全部) の実行時間が CPU 時間として計算されます。トランザクションの CPU 時間は非公開であり、他のトランザクションからは隔離されます。アプリケーションサーバの CPU 時間を消費しない操作は、CPU 時間にはカウントされません。
 

カウントされるもの

  • すべての Apex コード
  • Apex で公開されているライブラリ関数
  • ワークフローの実行

カウントされないもの

 

CPU タイムアウトを削減するためのベストプラクティス

「Apex Code Best Practices (Apex コードのベストプラクティス」を参考にして CPU タイムアウトを削減することができます。提案されている方法をいくつか見てみましょう。 
 

マップベースクエリの使用

List<Account> lstacc=[Select Id from Account limit 10000];
Set<Id> setIds=new Set<Id>();
for(Account a:lstacc){ //More CPU time for sure due to looping
setIds.add(a.id);
}

//Using Map query saves CPU time

//Fetching all account in map
Map<id,account> aMap = new Map<id,account>([Select Id,Name from Account limit 50000]);

//Creating list of accounts
List<account> accList = aMap.values() ;

//Creating set of ids

Set<id> accIds = aMap.keySet() ;
 

業務で非同操作を実行できるかどうかを確認する

ビジネスプロセスがリアルタイムでは実行されない場合があります。この場合は、@future でコードを実行できれば、コンテキストが中断されるため、非同期プロセスの CPU タイムアウト制限が 60 秒 (同期プロセスの 6 倍) になります。制限に達するリスクがある場合はこの方法を考慮してください。
 

集計 SOQL の使用

データベース時間は CPU 時間にカウントされませんので、ビジネスユースケースで集計 SOQL を使用できるかを常に確認するとよいでしょう。

たとえば、いくつかのレコードの項目値を集計するとします。集計に通常の for ループを使用している場合は、明らかに CPU 時間が費やされています。その代わりに、集計関数の SUM と AVG を使用して、計算処理がデータベース層で行われるようにしてください。これにより、データベース層に処理を負担させて CPU 時間を削減することができます。データベース層で集計やフィルタリングなどを作成できるか検討してください。データベース層に計算処理を負担させることで、CPU タイムアウト問題が発生する確率が低くなります。
 

必要なデータのみを取得してループを実行する

レコードのリストに対して for を実行する場合は、特定のデータに絞り込むことが重要です。ループが多すぎると CPU 時間が増加するためです。これは以前存在したスクリプトステートメントの制限の場合と同様です。

ナレッジ記事番号

000387833

 
読み込み中
Salesforce Help | Article