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

セレクティブ SOQL クエリを使用するカスタムインデックスによるパフォーマンスの向上

公開日: Jun 3, 2024
説明

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

重要: Salesforce SOQL クエリオプティマイザが高いレベルで動作することをこの記事で 説明するためあらゆる努力が払われてきましたが、その動作はパフォーマンスの今後の機能強化に対応するように通知なく変更される場合があります。開発者は開発者コンソールでクエリプランビュー (Summer '14 から使用可能) を使用し、影響を受ける SOQL クエリのクエリプランの生成時にオプティマイザによって提供される情報に基づいて、セレクティブでないクエリを調整できるようにすることをお勧めします。

また、インデックスによって DML のコストが増大する可能性があります。場合によっては、パフォーマンスに影響する可能性があるインデックスに基づいて、クエリオプティマイザが異なる方法で処理を実行する必要があります。


セレクティブ SOQL クエリ条件


クエリ検索条件の 1 つがインデックス付き項目にあり、そのクエリ検索条件によって、結果の行数がシステム定義のしきい値より少なくなる場合、そのクエリはセレクティブです。SOQL クエリのパフォーマンスは、WHERE 句で使用する 2 つ以上の検索条件が満たされた場合に改善されます。

選択しきい値は、初めの 100 万件のレコードの 10% とそれ以降のレコード件数の 5% 未満であり、最大 333,000 レコードです。インデックス付き標準項目であるクエリ検索条件がある場合など一部の状況では、しきい値が高くなる場合があります。また、選択しきい値は変更される可能性があります。


セレクティブ SOQL クエリのカスタムインデックスに関する考慮事項


次の項目はデフォルトでインデックスが付けられます。
  • 主キー (Id、Name、OwnerId 項目)
  • 外部キー (参照関係または主従関係項目)
  • 監査日付 (SystemModStamp など) 
  • 外部 ID または一意としてマークされたカスタム項目
       

Salesforce サポートは、お客様からの要求に応じてカスタムインデックスを追加できます。


サポートへのケースを作成する場合、インデックス付けされる項目が WHERE 句に検索条件として含まれる SOQL クエリを必ず含めてください。また、バインド値がある場合は、バインド値を必ず含めてください。

SOQL カスタムインデックスリクエストのチェックリスト (英語) に記載されているすべての情報をサポートに提供してください。
インデックス付けする項目を決定するには、SOQL クエリを選択的にする方法を参照し、「クエリプランツール」に記載されているように開発者コンソールでクエリプラン分析を実行することもできます。

カスタムインデックスは、次の種別の項目では作成できません。
  • 複数選択リスト。
  • マルチ通貨組織の通貨項目。
  • ロングテキスト項目。 
  • バイナリ項目 (blob、ファイル、または暗号化されたテキストの種別の項目) 

注意: Salesforce には新しいデータ型 (一般に複雑なデータ型) が追加される場合がありますが、このデータ型の項目のカスタムインデックス付けは許可されない場合があります。
       
通常、次の場合はカスタムインデックスが使用されません。
  • クエリの対象の値が上記のシステム定義のしきい値を超える。
  • 検索条件の演算子が、NOT EQUAL TO (または !=)、NOT CONTAINS、NOT STARTS WITH などの否定演算子である。
  • 検索条件に CONTAINS 演算子が使用され、スキャンされる行数が 333,000 を超える。これは、CONTAINS 演算子にはインデックスの完全スキャンが必要なためです。このしきい値は変更される場合があります。
  • 空の値と比較している場合 (Name != '')。

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


セレクティブ SOQL クエリの例

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

クエリ 1:

   
SELECT Id FROM Account WHERE Id IN (<list of account IDs>)

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

クエリ 2:

   
SELECT Id FROM Account WHERE Name != ''

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

クエリ 3:

   
SELECT Id FROM Account WHERE Name != '' AND CustomField__c = 'ValueA'

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

クエリ 4:

   
SELECT Id FROM Account WHERE FormulaField__c = 'ValueA'

数式項目にインデックスを付けるには、以下のルールが true である必要があります。

  • 数式に 1 つのオブジェクトの項目のみが含まれる (リレーション項目ではない)。
  • 数式項目が非決定的関数 (SYSDATE など) を参照していない。
  • 数式項目が、インデックスに含める項目としてサポートされない項目を参照していない。このリストはどこにも具体的に文書化されていません (多くの特別な事例があります)。Spring 12 (176) では createdById はサポートされていませんでしたが、Summer 12 (178) ではサポートされています。CreatedDate も同様です。
  • 数式項目に主キー (Id など) への参照項目が含まれていない。 
  • 数式項目で TEXT(<picklist-field>) 関数を使用していない。
  • 数式が参照項目を参照している場合、その項目のオプション [参照レコードが削除された場合の対処方法] を [この項目の値をクリアします] に設定することはできません。

上記のいずれかの条件が false の場合、項目に対して [インデックスの追加] は表示されません。

注意: SOQL クエリのパフォーマンスが Salesforce サポートにより分析され、基準が満たされた場合は、インデックス付けが実行されます。

ナレッジ記事番号

000385213

 
読み込み中
Salesforce Help | Article