今回はこちらのTrailheadの内容から開発の際に頭に入れるべきSOQLの組み立て方について解説していこうと思います。
効率的なクエリの作成
効率的なクエリの作成
ガバナ制限
参考:実行ガバナと制限
今回の目的である、効率なクエリの作成をする目的とはなんでしょうか。
まずsalesforceはマルチテナントプラットフォームである為、限られたリソースを共有しています。
その為、実行できるDMLや、クエリの発行数、一度で取得できるレコードの数などに制限を持たせています。
それがガバナ制限といいます。
下記は上記リンク先からの転用になりますがガバナ制限の表になります。
説明 | 同期制限 | 非同期制限 |
---|---|---|
発行される SOQL クエリの合計数1 | 100 | 200 |
SOQL クエリによって取得されるレコードの合計数 | 50,000 | |
Database.getQueryLocator によって取得されるレコードの合計数 | 10,000 | |
発行される SOSL クエリの合計数 | 20 | |
1 つの SOSL クエリによって取得されるレコードの合計数 | 2,000 | |
発行される DML ステートメントの合計数2 | 150 | |
DML ステートメントの結果として処理されるレコードの合計数、Approval.process、または database.emptyRecycleBin | 10,000 | |
insert、update、または delete ステートメントによって繰り返しトリガする Apex 呼び出しのスタックの深さの合計数 3 | 16 | |
トランザクション内のコールアウト (HTTP 要求または Web サービスコール) の合計数 | 100 | |
トランザクション内のすべてのコールアウト (HTTP 要求または Web サービスコール) のタイムアウトの最大累積値 | 120 秒 | |
Apex 呼び出し 1 回につき許可される future アノテーションを持つメソッドの最大数 | 50 | batch および future のコンテキストの場合 0、queueable コンテキストの場合 1 |
System.enqueueJob によってキューに追加される Apex ジョブの最大数 | 50 | 1 |
許可される sendEmail メソッドの合計数 | 10 | |
ヒープの合計サイズ 4 | 6 MB | 12 MB |
Salesforce サーバの最大 CPU 時間5 | 10,000 ミリ秒 | 60,000 ミリ秒 |
Apex トランザクションごとの最大実行時間 | 10 分 | |
Apex トランザクションごとに許容されるプッシュ通知メソッドコールの最大数 | 10 | |
各プッシュ通知メソッドコールで送信できるプッシュ通知の最大数 | 2,000 |
開発の際は上記のことを気にしつつ、設計およびプログラミングの必要があります。
さらに言うと組織としてのAPI呼び出し数やバッチの数などもありますので、
上記以外のことも知っておく必要があります。(それはまた別の機会に)
セレクティブクエリの作成
さてガバナ制限がなぜあるのかを知った上で、今回のタイトルである、
効率的なクエリを作成するために必要な知識を紹介していきます。
Trailheadによると、
何よりも早くシステムをクラッシュさせる一番の要因はパフォーマンスが悪いクエリです。
効率的なクエリの作成
ではパフォーマンスの良いクエリとはなんなんでしょうか。
そこで出てくるのがセレクティブクエリです。セレクティブクエリを使うとテーブルの完全スキャンをすることなくインデックスを使用するため、大規模なデータを扱う際に重要となるようです。
セレクティブクエリとはインデックスのついた項目『パワー項目』をWhere句に指定し、高速に処理されるクエリのことです。
インデックスのついた項目と言うのが下記になります。
インデックス付き項目 | 説明 |
---|---|
Id | システムによって生成された一意の 18 文字の項目。これはオブジェクトの主キーです。 |
Name | テキストベースの項目。 |
OwnerId | オブジェクトの所有者への参照。 |
CreatedDate | レコードが作成された日時。 |
SystemModStamp | レコードの最終更新日を含む参照のみの項目。この項目にはインデックスが付けられますが、類似の LastModifiedDate には付けられないため、クエリ内ではこの項目を使用することを検討します。 |
RecordType | RecordType の ID。RecordType は、特定のユーザに対して異なる UI 結果を提供するために使用されます。 |
主従項目 | 主従関係を示すために使用される外部キー項目。 |
参照項目 | 参照関係を示すために使用される外部キー項目。 |
一意の項目 | カスタム項目を作成時に一意であるとマークすることができます。それによって、自動的にインデックスが付けられます。 |
外部 ID 項目 | 一意の項目と同様に、これらのカスタム項目を外部 ID としてマークできます。これらは主にインテグレーションのために使用されます。 |
セレクティブでなくなる例外
上記の表にある項目をWhere句に入れておけば大丈夫なんだねわかった。とここで読むのをやめないでくださいね。
たとえインデックスがある『パワー項目』を使ったとしても、Where句での条件によってはセレクティブクエリにならないケースがあるようです。
それが下記4種類です。
- null 行に対するクエリ — 項目が空または null であるレコードを探すクエリ。
- 否定的な絞り込み演算子 — クエリ内での !=、NOT LIKE、EXCLUDES などの演算子の使用。
- 先頭のワイルドカード — 次のように先頭にワイルドカードを使用するクエリ。
- 比較演算子を使用したテキスト項目 — テキストベースの項目での >、<, >=、<= などの比較演算子の使用。
上記のような例外があるようです。
そこで実行するクエリがパフォーマンスの良いクエリかを確認できる方法があるようです。
クエリ実行プランツール
開発者コンソールからクエリが実行できるのはご存知だとして話を進めます。
開発者コンソールのHelp→Preferencesを押してください。
するとEnable Query PlanというのがあるのでこれをTrueに設定します。

するといつものクエリエディタのExecuteの横にQuery Planというボタンが追加されていると思います。
ここで実行するクエリを試してみてください。
今回はTrailheadで出ていた2つのクエリを確認してみました。
まず1つめが!=のついているクエリになります。この場合はセレクティブクエリの例外となり、
テーブルスキャンとなります。

二つ目はセレクティブクエリですのでインデックスから取得する旨が返ってきます。

このようにして、コーディングで作成するクエリの効率を確認することができます。
組織全体を考えた実装をしていくのにベストなツールですのでしっかり確認をしていきましょう。
コメント