効率的なクエリの作成
学習の目的
この単元を完了すると、次のことを理解できるようになります。
- Force.com クエリオプティマイザーがクエリのパフォーマンスを最適化するしくみ。
- セレクティブクエリの使用がクエリのパフォーマンスに及ぼす影響 。
- クエリ実行プランツールを使用して検索クエリを評価する方法。
制限
効率的なクエリはパフォーマンスが高くなるだけではなく、ガバナ制限に関する問題が発生しないようにするのにも役立ちます。これはマルチテナントプラットフォームであるため、全員がスペースを共有しているということを忘れないでください。そして、何よりも早くシステムをクラッシュさせる一番の要因はパフォーマンスが悪いクエリです。ガバナ制限はそのためにあります。
ガバナ制限はリソースの審判のようなものであると考えてください。全員がルールに従ってプレーし、リソースを平等に使用できるようにします。
この単元では、ガバナ制限によって制限されることを避けるために、検索クエリを最適化するための方法を学習します。
Force.com クエリオプティマイザー
Salesforce のバックエンドデータベースは Oracle を使用していますが、Force.com では独自のバージョンのクエリオプティマイザーを使用してコストベースでクエリを評価します。ほとんどのコストベースのクエリオプティマイザーと同様に、Salesforce が使用するクエリオプティマイザーもデータについて収集された統計に依存します。ほとんどの統計は週ごとに収集されますが、1 時間ごとにキャッシュされる事前クエリもシステムによって生成されます。
クエリオプティマイザーは SOQL クエリと SOSL 検索を評価します。交通警官のような役割を果たし、クエリを適切なインデックスに転送します。すべての受信クエリを調べて、可能性のあるクエリパスを特定し、各パスにコスト値を割り当てます。そして、これらのコストを使用してどの実行プランを使用するかを決定します。
正直に言うと、クエリオプティマイザーが実行プランを選択し、しきい値を操作する方法は、少々複雑です。けれども、.NET 開発者の皆さんなら、きっとこの挑戦に意欲的に取り組むことでしょう。この単元の完了後に「リソース」セクションのリンクを参照することで、さらに学習を深めることができます。
ベストプラクティス
.NET 開発者の皆さんはおそらくベストプラクティスについて考えるのが好きでしょう。困難な課題に意欲的に取り組み、常に最良の方法を探しているのではないでしょうか。こうした認識に基づき、高速で効率的な検索クエリを作成するためのベストプラクティスを紹介します。
セレクティブクエリの作成
最初の単元では、SOQL ステートメントについて取り上げ、WHERE 句を使用して検索条件を適用する方法について説明しました。AND 句や OR 句を使用して複数の項目を組み合わせることもできます。
そして、これを聞いても驚かないと思いますが、より多くの項目を WHERE 句に含めることは良いことです。明らかに、クエリが返すデータが少ないほど良いからです。ただし、ご存じないかもしれませんが、すべての項目が同じというわけではありません。一部の項目は「パワー」項目であると考えることができます。これらのパワー項目を WHERE 句に使用すると、クエリは非常に高速になります。
これらのパワー項目のパワーの秘密は何でしょうか。それはもちろんインデックスです。
すべての標準テーブルとカスタムテーブルにおいて、特定の項目は自動的にフラグが設定されてインデックスが付けられます。例として次のような項目があります。
インデックス付き項目 | 説明 |
---|---|
Id | システムによって生成された一意の 18 文字の項目。これはオブジェクトの主キーです。 |
名前 | テキストベースの項目。 |
OwnerId | オブジェクトの所有者への参照。 |
CreatedDate | レコードが作成された日時。 |
SystemModStamp | レコードの最終更新日を含む参照のみの項目。この項目にはインデックスが付けられますが、類似の LastModifiedDate には付けられないため、クエリ内ではこの項目を使用することを検討します。 |
RecordType | RecordType の ID。RecordType は、特定のユーザーに対して異なる UI 結果を提供するために使用されます。 |
主従項目 | 主従関係を示すために使用される外部キー項目。 |
参照項目 | 参照関係を示すために使用される外部キー項目。 |
一意の項目 | カスタム項目を作成時に一意であるとマークすることができます。それによって、自動的にインデックスが付けられます。 |
外部 ID 項目 | 一意の項目と同様に、これらのカスタム項目を外部 ID としてマークできます。これらは主にインテグレーションのために使用されます。 |
これらのインデックス付き項目のいずれかをクエリの WHERE 句で使用すると、クエリがセレクティブとみなされ、テーブルの完全スキャンではなくインデックスが使用される可能性が高くなります。大規模なデータベースを扱っている場合は、これは極めて重要です。
メモ: Salesforce のお客様は Salesforce サポートにカスタムインデックスを依頼することができます。それには、サポートケースを作成し、インデックスを付ける項目を使用した SOQL クエリを含めます。
インデックスを使用してもセレクティブでなくなる例外
インデックス付き項目をクエリで使用しても必ずうまくいくわけではありません。クエリ内の操作によってクエリが非セレクティブになり、テーブルの完全スキャンが行われてしまう可能性があります。クエリを作成する時には、常に次のことを避けるようにします。
- 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
クエリ実行プランツール
開発者コンソールには、クエリを高速化するための簡便なツールが含まれています。このツールを使用することで、クエリオプティマイザーのバックグラウンドでの動作を確認することができます。クエリ実行プランツールはデフォルトでは有効になっていません。次の手順を実行して有効にします。
- [設定] メニューから、[開発者コンソール] を選択して開発者コンソールを開きます。
- 開発者コンソールで、[Help (ヘルプ)] > [Preferences (設定)] を選択します。
- [Enable Query Plan (クエリプランを有効化)] を選択し、true に設定されていることを確認します。
- [保存] をクリックします。
- [Query Editor (クエリエディター)] タブで、[Query Plan (クエリプラン)] ボタンが [Execute (実行)] ボタンの横に表示されていることを確認します。
クエリ実行プランツールが有効になったので、このツールを使用してクエリを評価できます。まず、パフォーマンスが悪いクエリを評価してみましょう。
- 開発者コンソールで、下部ペインの [Query Editor (クエリエディター)] タブをクリックします。
- 既存のコードを削除して、次のスニペットを挿入します。
SELECT Id, CaseNumber FROM Case WHERE Status != 'New'
- [Query Plan (クエリプラン)] をクリックします。
[Query Plan (クエリプラン)] ダイアログにクエリのコストが一覧表示されたテーブルと、TableScan が実行されるということが表示されます。これは良くないことです。下部ペインに表示されている結果の詳細な説明を確認します。
次に、最初のクエリと同じ結果を取得する別のクエリを見てみましょう。
- 下部ペインの [Query Editor (クエリエディター)] タブをクリックします。
- 既存のコードを削除して、次のスニペットを挿入します。
SELECT Id, CaseNumber FROM Case WHERE IsClosed = true
- [Query Plan (クエリプラン)] をクリックします。
[Query Plan (クエリプラン)] ダイアログにクエリのコストが一覧表示されたテーブルが表示されますが、今回は、インデックスを使用できることを示す別の行が表示されます。
クエリ実行プランツールを実行したどちらのクエリも取得する行数は同じですが、選択した項目と演算子によって実行プランは大きく異なっています。開発組織ではデータが少ないためこれらの違いは小さいように見えますが、何百万件ものレコードがある組織でクエリを比較する場合はこれらの違いが非常に重要になる場合があります。
クエリ実行プランツールの各列に表示される内容についての詳細は、「リソース」のクエリ実行プランツールに関するリンクを参照してください。
もうひとこと...
非決定性数式項目を使用したクエリを作成することは常に避けるように努めます。数式項目は、実行時に項目の値を動的に計算できるカスタム項目です。これらの種類の項目は、ほとんどの組織で人気があり、過剰に使用されがちです。数式項目の値が時間の経過に伴って変動する場合、その項目は非決定的であるとみなされます。詳細は、「リソース」の SOQL のNULL 項目や数式項目のベストプラクティスについてのリンクを参照してください。
残念ながら、クエリ実行プランツールを使用して SOSL クエリを評価することはできませんが、だからといって、それらの種類のクエリではパフォーマンスについて考慮しないということはありません。SOSL クエリを記述するときに避けるべき事項についての詳細は、「リソース」のベストプラクティスとパフォーマンスのヒントへのリンクを参照してください。
リソース
- FAQ - Force.com クエリオプティマイザー
- Make SOQL Query Selective (SOQL クエリをセレクティブにする方法)
- クエリプランツール (使い方 & よくある質問)
- Force.com SOQL Performance Tips: LastModifiedDate vs SystemModStamp (Force.com SOQL のパフォーマンスに関するヒント: LastModifiedDate と SystemModStamp)
- Force.com SOQL Best Practices: Nulls and Formula Fields (Force.com SOQL ベストプラクティス: NULL 項目と数式項目)