この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

非常に大きい SOQL クエリの処理

SOQL クエリがヒープサイズの制限を超える多数の sObjects を返し、エラーを引き起こす場合があります。問題を解決するには、代わりに SOQL クエリ for ループを使用します。query および queryMore への内部コールが使用されるため、レコードの複数の一括処理が可能になります。

たとえば、結果が大きすぎる場合、次の構文で実行時例外が発生します。

代わりに、次の例のいずれかで SOQL クエリ for ループを使用します。

次の例は、レコードの一括更新に使用する SOQL クエリ for ループを示します。指定された条件に一致する姓名を持つ取引先責任者のすべてのレコードで、取引先責任者の姓を変更するとします。

for ループで SOQL クエリを使用する代わりに、Apex の一括処理を使用してレコードを一括更新すると、ガバナ制限に達するリスクが最小限に抑えられます。

詳細は、SOQL For ループを参照してください。

より効率的な SOQL クエリ

最高のパフォーマンスを得るためには、特にトリガ内のクエリに対しては、セレクティブ SOQL クエリを使用する必要があります。実行時間が長時間に渡ることを回避するために、セレクティブ以外の SOQL クエリはシステムより終了される場合があります。100,000 件を超えるレコードを含むオブジェクトに対してトリガでセレクティブではないクエリを使用すると、エラーメッセージが表示されます。このエラーを回避するには、必ずセレクティブクエリを使用します。

セレクティブ SOQL クエリ条件
  • クエリ検索条件の 1 つがインデックス付き項目にあり、そのクエリ検索条件によって結果となる行数がシステム定義のしきい値より少なくなる場合、そのクエリはセレクティブです。SOQL クエリのパフォーマンスは、WHERE 句に使用される 2 つ以上の検索条件がその条件を満たす場合に改善されます。
  • 選択度しきい値は、初めの 100 万レコードについてはレコードの 10% で、以降のレコードから最大 333,333 個のレコードについては 5% になります。インデックス付き標準項目のクエリ検索条件などの一部の状況では、しきい値が��くなる場合があります。また、選択度しきい値は変化します。
セレクティブ SOQL クエリのカスタムインデックスに関する考慮事項
  • 主キー (ID、名前、所有者項目)、外部キー (ルックアップまたは主従関係項目)、監査日付 (LastModifiedDate など)、および外部 ID または一意としてマークされたカスタム項目は、デフォルトでインデックスが付けられます。
  • 頻繁に実行されるクエリのパフォーマンスがインデックスによって向上することが Salesforce オプティマイザによって確認された場合、デフォルトでインデックスが付けられない項目に、後から自動的にインデックスを付けることができます。
  • Salesforce.com サポートは、お客様からの要求に応じてカスタムインデックスを追加できます。
  • カスタムインデックスは、複数選択リスト、マルチ通貨組織の通貨項目、ロングテキスト項目、一部の数式項目、およびバイナリ項目 (blob 型の項目、ファイル、または暗号化されたテキスト項目) では作成できません。新しいデータ型 (一般的に複雑なデータ型) は Salesforce に追加できますが、これらの項目にはカスタムインデックスを使用できません。
  • 通常、カスタムインデックスは次の場合に使用されません。
    • クエリされた値が前述のシステム定義のしきい値を超える
    • 検索条件の演算子が、NOT EQUAL TO (または !=)、NOT CONTAINS、および NOT STARTS WITH などの負の演算子である
    • 検索条件に CONTAINS 演算子が使用されており、スキャンされる行数が 333,333 を超える。これは、CONTAINS 演算子にインデックスの完全スキャンが必要であるためです。このしきい値は変化します。
    • 空の値と比較している (Name != '')

    ただし、カスタムインデックスが使用されない複雑なシナリオは他にもあります。ここに記載された条件以外のシナリオがある場合、またはセレクティブではないクエリに関するヘルプが必要な場合は、Salesforce.com カスタマーサポートにお問い合わせください。

セレクティブ SOQL クエリの例
大きなオブジェクトでのクエリがセレクティブであるかどうかを理解するために、いくつかのクエリを解析することにします。これらのクエリについては、Account sObject に 100,000 件を超えるレコード (削除されたレコードがごみ箱に残っている、論理削除されたレコードを含む) があると仮定します。
クエリ 1:

WHERE 句は、インデックス付き項目 (ID) に使用されています。SELECT COUNT() FROM Account WHERE Id IN (<list of account IDs>) が選択度しきい値より少ないレコードを返す場合、ID へのインデックスが使用されます。これは、ID のリストに少ない数のレコードが含まれるため、一般的なケースです。

クエリ 2:

名前はインデックス付きですが (主キー) Account は大きなオブジェクトであるため、この検索条件はほとんどのレコードを返すことから、クエリは非セレクティブとなります。

クエリ 3:

ここでは、各検索条件が個別に考慮された場合にセレクティブであるかどうかを確認する必要があります。前の例で確認したように、最初の検索条件はセレクティブではありません。そのため、2 つの検索条件を重点的に確認することにします。SELECT COUNT() FROM Account WHERE CustomField__c = 'ValueA' が返すレコードの件数が選択度しきい値より少なく、かつ CustomField__c がインデックス付きである場合、このクエリはセレクティブです。