大量件数の処理を行う場合、Apex Batchを使用して対応します。『execute』の処理でクエリ実行件数などはリセットされるのでガバナ制限もほとんど気にしなくていいのですが、気をつけなければならない制限もあると思うので約123,000件の取引先を使って検証してみました。
こんな感じのバッチ処理です。
- 取引先を全件取得
- 取引先のチェックボックス項目を変更して更新
- バッチの処理結果はバッチログオブジェクトに登録
コードはこんな感じ
バッチは開発者コンソールから実行します。
バッチ処理完了時の『Apex Jobs』です。きちんと正常終了しています。
finish処理終了時の『CUMULATIVE_LIMIT USAGE』です。
Limits Classで確認できる処理情報です。
『execute』処理で毎回実行されたDMLの実行回数はリセットされているので、12万件のレコードを処理しても特に制限にかかる心配はありません。※一番気になるHeapSizeも特に問題ありませんでした。
Batch Logです。
Record Countの項目は『execute』処理の中でカウントアップしていますが、正常に全件分カウントされていることを確認できます。シンプルな処理ということもありますが、12万件の更新処理は約5分で完了しました。
取引先のチェック項目は正常に更新されています。
100万件とか1000万件とかもっと大量の件数でも確認してみたいのですが、とりあえず10万件ぐらいなら何の制限にも引っかかることはありませんでした。
おまけ
Apexバッチといえばバッチサイズを指定することができます。通常200件で実行しますが、2000件など大きい値を指定すれば処理実行時間が短縮されます。(エラー発生時に一度にエラーになる件数も多くなりますが...)
約12万件の件数を処理するのに5分程掛かりました。もう少し多くした場合どのくらい違いが出るのか確認してみます。
Batch Size = 2000件で実行
チェックボックスをTrueからFalseに更新するのでこんな感じです。
実行結果です。Total Batchesは約600件から約60件まで小さくなりましたが、処理の実行時間はあまり変わりませんでした。Jobが登録されてから処理が実行されるまで少し時間が掛かった気がしました。
バッチサイズに指定できる上限ですが、たしか2000件だったと思います。開発者ドキュメントに次の記載がありました。
If the start method of the batch class returns a QueryLocator, the optional scope parameter of Database.executeBatch can have a maximum value of 2,000. If set to a higher value, Salesforce chunks the records returned by the QueryLocator into smaller batches of up to 2,000 records. If the start method of the batch class returns an iterable, the scope parameter value has no upper limit; however, if you use a very high number, you may run into other limits.
というわけで今回確認した感じでは約10万件のレコードならバッチサイズによる影響はそれほどなさそうな感じでした。(処理のバラつき等あると思うのでもしかするともっと早く終ることもあるかもしれません。)
※一応もう一度実行して確認してみました。
さいごに
startメソッドで実行されるDatabase.QueryLocatorオブジェクトは、最大で5千万件のレコードを返せます。それ以上はエラーになるみたいです。
今回の検証コードはこちらです。