ガバナ制限を超えない!Salesforce SOQL & SOSL クエリ最適化の方法


Salesforce SOQL & SOSL パフォーマンスチューニング:効率的なクエリの書き方

Salesforceにおけるデータ取得は、アプリケーションのパフォーマンス、スケーラビリティ、ユーザー満足度に直結します。ガバナ制限を遵守しながら効率的なSOQLおよびSOSLクエリを実装することは、開発者にとって必須のスキルです。ここでは、SOQLとSOSLのパフォーマンスを最適化するためのベストプラクティスを解説します。


1. ガバナ制限とパフォーマンスへの影響

Salesforceのガバナ制限は、マルチテナント環境におけるリソースの公平な使用を保証するために設けられています。例えば:

  • SOQLクエリ数制限: 同一トランザクションでの最大100(同期)〜200(非同期)クエリ

  • SOSLクエリ数制限: 同一トランザクションで最大20クエリ

  • レコード取得制限: 1クエリで最大50,000件のレコード

  • クエリタイムアウト: 120秒を超えるクエリは中断される

これらの制限を超えないよう、クエリは効率的に設計する必要があります。


2. SOQL パフォーマンスチューニングのベストプラクティス

2.1 インデックス付きフィールドを使ったセレクティブクエリ

  • 概要:
    インデックス付きフィールド(例: Id, Name, 外部ID、CreatedDate、SystemModstamp)をWHERE句で使用すると、データベースのスキャンが減少し、クエリ実行速度が向上します。

  • 例: 非セレクティブ vs セレクティブクエリ

    • 非セレクティブ:

      SELECT Id FROM Account WHERE Industry = 'Tech' AND AnnualRevenue > 1000000
      
    • セレクティブ(CreatedDateインデックス使用):

      SELECT Id FROM Account WHERE Industry = 'Tech' AND CreatedDate = LAST_N_DAYS:30
      

2.2 WHERE、LIMIT、ORDER BY句の最適化

  • WHERE句:
    インデックス付きフィールドを使用し、関数(例: CALENDAR_YEAR(CreatedDate))の使用を避ける。

  • LIMIT:
    取得するレコード数を制限し、不要なデータ取得を回避する。

  • ORDER BY:
    インデックス付きフィールドでソートし、追加のソート処理を最小化する。

2.3 バルク処理の実装

  • 概要:
    ループ内でクエリを実行するのではなく、ループ外で一括クエリを実行することで、ガバナ制限のSOQLクエリ数を削減します。

  • 悪い例:

    for (Contact c : contacts) {
        Account acc = [SELECT Name FROM Account WHERE Id = :c.AccountId];
    }
    
  • 良い例:

    Set<Id> accountIds = new Set<Id>();
    for (Contact c : contacts) {
        accountIds.add(c.AccountId);
    }
    Map<Id, Account> accounts = new Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id IN :accountIds]);
    

2.4 リレーションシップクエリとジョイン

  • 親子サブクエリ:
    1つのクエリで関連レコードをまとめて取得できます。

    SELECT Name, (SELECT LastName FROM Contacts) FROM Account
    
  • 親フィールドの直接取得:
    例: SELECT Contact.Account.Name FROM Contact

2.5 大規模データの処理

  • 戦略:
    50,000件を超えるデータには、日付範囲やBatch Apexを使用して、データを小分けに処理する。

  • OFFSETの回避:
    OFFSETは大量データではパフォーマンスに影響するため、インデックス付きフィルターで代替する。


3. SOSL パフォーマンスチューニングのベストプラクティス

3.1 正確な検索用語の使用

  • 概要:
    ブロードな検索キーワードは大量のレコードを返す可能性があるため、AND、OR、NOTなどの論理演算子を活用し、検索範囲を絞ります。

  • 例:

    FIND {apple AND (fruit OR tech)} IN ALL FIELDS RETURNING Account(Name), Contact(LastName)
    

3.2 オブジェクトとフィールドのスコープ制限

  • 概要:
    検索対象のオブジェクトやフィールドを RETURNING 句で指定し、不要なデータ取得を防ぎます。

  • 例:

    FIND {Acme} IN NAME FIELDS RETURNING Account(Name, BillingCity), Opportunity(Amount)
    

3.3 結果件数の管理

  • 概要:
    SOSLクエリは、合計2,000件まで返すため、LIMIT句で各オブジェクトの結果件数を制御します。

  • 例:

    FIND {Cloud} RETURNING Account(Name LIMIT 100), Contact(LastName LIMIT 50)
    

4. 一般的なベストプラクティス

4.1 結果のキャッシュ

  • 方法:
    頻繁にアクセスするデータは、静的変数やコレクションにキャッシュして再利用し、データベースコールを減らします。

4.2 パフォーマンスの分析

  • ツール:

    • Query Plan Tool: Developer Consoleを使ってクエリプランを確認し、インデックス使用状況をチェックします。

    • デバッグログ: 実行時間や取得行数を確認して、ボトルネックを特定します。

4.3 効率的なデータ構造の利用

  • 方法:
    クエリ結果をMapに変換することで、O(1)アクセスを実現し、効率的にデータを操作します。


5. まとめ

効率的なSOQLおよびSOSLクエリの作成は、Salesforceのガバナ制限を守りつつアプリケーションのパフォーマンスを最適化するために不可欠です。

  • SOQL:
    インデックス付きフィールドの利用、適切なWHERE・LIMIT・ORDER BY句の設定、バルククエリの実装、リレーションシップクエリの活用がポイントです。

  • SOSL:
    正確な検索用語の指定、オブジェクト・フィールドのスコープ制限、結果件数の管理が重要です。

  • 一般的な最適化:
    結果のキャッシュやパフォーマンス分析、効率的なデータ構造の活用を行い、リソースの無駄を最小限に抑えます。

これらのベストプラクティスを実装することで、Salesforceでのデータ取得が高速かつ効率的になり、アプリケーションのスケーラビリティが向上します。
常に最新のパフォーマンスデータを確認し、必要に応じてクエリを最適化することが、長期的な成功の鍵です。

コメント