【Salesforce】SOQLのパフォーマンスチューニング


前提としてすべきこと

パフォーマンスチューニングをし易くするためには、DAOクラスを用意してSOQLを発行する処理を纏めるのが得策です。
SOQL発行が様々なクラスに散らばっていると、パフォーマンスチューニングがし難くなります。
以下のようにオブジェクトごとにDAOクラスを作って、SOQL発行処理を纏めましょう。

public with sharing class AccountDAO {

    public static List<Account> getAccountByPhone(String phone){
        return [
                SELECT Id, Name, Phone
                FROM Account
                WHERE Phone =: phone
                ];
    }

    public static List<Account> getAccountById(Id id){
        return [
                SELECT Id, Name, Phone
                FROM Account
                WHERE Id =: id
                ];
    }

}

インデックスを付与する

インデックスとは索引です。
このインデックスが割り当てられている項目は、DBの中で何がどこにあるかをざっくり把握しているようなイメージとなります。
なので、インデックスが付与されている項目を条件に加えるとSOQLの実行速度が上がります。

Salesforceでは、標準設定として以下の項目にはインデックスが振られております。
 ・RecordTypeId
 ・Division
 ・CreatedDate
 ・SystemModStamp(LastModifiedDate)
 ・Name
 ・Email(取引先責任者とリード)
 ・ID
カスタム項目にインデックスを割り当てる事も可能です。
方法としては3つあります。

・カスタム項目にインデックスを割り当てる方法①:外部IDに設定する。
  項目定義にて「外部ID」にチェックを入れればOKです。

・カスタム項目にインデックスを割り当てる方法②:値をユニークに制限する。
  項目定義にて「ユニーク」にチェックを入れればOKです。

・カスタム項目にインデックスを割り当てる方法②:テクニカルサポートに依頼する。
  外部キーもしくはユニーク制限をしたくない場合は、テクニカルサポートに依頼することでインデックスを付与する事が可能です。

インデックス項目を条件に加える

以下のようにインデックス項目をSOQLの条件に加えれば、実行速度が上がります。


SELECT Id, Name, Phone
FROM Account
WHERE CreatedDate > 2020-10-08T01:02:03Z

インデックスを使用しても、実行速度が上がらないパターン

注意が必要なのは、インデックス項目を使用しても実行速度が上がらないパターンがあります。
以下がそのパターンです。

・null 行に対するクエリ— 項目が空または null であるレコードを探すクエリ。

SELECT Id, Name FROM Account WHERE Custom_Field__c = null

・否定的な絞り込み演算子 — クエリ内での !=、NOT LIKE、EXCLUDES などの演算子の使用。

SELECT CaseNumber FROM Case WHERE Status != New

・先頭のワイルドカード — 次のように先頭にワイルドカードを使用するクエリ。

SELECT Id, LastName, FirstName FROM Contact WHERE LastName LIKE %smi%

・比較演算子を使用したテキスト項目 — テキストベースの項目での >、<、>=、<= などの比較演算子の使用。

SELECT AccountId, Amount FROM Opportunity WHERE Order_Number__c > 10

SOQLの評価ツール「Query Plan」

SOQLの評価には、「Query Plan」という機能を使います。
まずは開発者コンソールにて、この機能を有効化します。
Help>Preferencesをクリックします。

Enabel Query Planにチェックを入れ保存します。

これで、Query EditorタブのExecuteボタンの横に「Query Plan」ボタンが表示されます。

Query Planの使い方

使い方は簡単、SOQLを入れて「Query Plan」を押下するだけです。

以下SOQLで試してみましょう。

SELECT Id, Name, Phone
FROM Account

「Query Plan」を押下すると、以下画面が立ち上がりました。
Leading Operation Typeを見れば分かるように、TableScanされています。
要はインデックス項目が条件に無いため、全てのレコードを検索してます。
Costとしては、2.593掛かっております。

では以下のSOQLだとどうでしょうか。
インデックス項目である「CreatedDate」を条件に加えております。

SELECT Id, Name, Phone
FROM Account
WHERE CreatedDate > 2020-10-08T01:02:03Z

2プラン表示されました。
SOQL実行時には最もCostが掛からないプランが採用されるので、当然Leading Operation TypeがIndexのプランが採用されます。
CreatedDateを検索条件に加えた事により、Costが2.593⇒0.8に下がりました。
Costが下がれば実行速度も上がります。
評価ツールによって、インデックス項目を条件に加えると実行速度が上がる事が確認できました。