データのクエリおよび検索の実行
学習の目的
この単元を完了すると、次のことができるようになります。
- 大量データの処理時にパフォーマンスを損なうことなくクエリを実行する。
- 一括クエリを使用して、大規模なデータセットに効率的にクエリを実行する。
- 使用頻度の高い項目をまとめたスキニーテーブルを使用するメリットを説明する。
検索アーキテクチャ
組織に膨大なデータを保存すればパフォーマンスに影響する可能性があり、間違いなく検索にも影響が及びます。検索とは、自由形式のテキストに基づいてレコードを照会する機能です。Salesforce の検索アーキテクチャは、独自のデータストアに基づき、そのテキストの検索向けに最適化されています。
データが検索されるためには、事前にインデックスが付けられている必要があります。Force.com では大半のテキスト項目に自動的にインデックスが付けられるため、ユーザーがクロスオブジェクト検索を実行して、目的の文字列を含むレコードをすぐさま見つけることができます。インデックス検索を実行すると、まず適切なレコードのインデックスが検索され、次にアクセス権限、検索制限、その他の検索条件に基づいて結果が絞り込まれます。
そして、通常は関連性が最も高い結果を含む結果セットが作成されます。結果セットが事前定義されたサイズに達すると、残りのレコードが破棄されます。続いて、この結果セットを使用してデータベースのレコードが照会され、ユーザーに表示される項目が取得されます。大量のデータが追加または変更されている場合には、このプロセス全体に時間がかかることがあります。
クエリの使用
次のシナリオを考えてみてください。無駄のないオブジェクトがあるとします。インテグレーションやカスタムの Visualforce ページのコードはすべて記述され、テストデータではきちんと動作していました。顧客がシステムを使い始めたときも、すべてうまくいっていました。ただし、組織に大量データが読み込まれたり蓄積されたりした時点で、パフォーマンスが大幅に低下し始めます。
この解決策となるのがクエリの作成です。クエリは、LDV を処理できる組織の設計において鍵を握ります。ここで重要な点は、選択的なリストビュー、レポート、SOQL クエリを設計することと、クエリの最適化について理解することです。
SOQL クエリと SOSL クエリ
検索には、SOQL クエリと SOSL クエリのいずれかを使用してアクセスできます。SOQL は Force.com のデータベースクエリ言語で、SQL に似ています。SOQL は、子-親リレーション (多くの場合は多対一) のクエリや、親-子リレーション (ほぼすべてが一対多) のクエリに使用できます。
SOSL は Force.com の全文検索言語です。SOSL では項目内の複数の用語をトークン化して、そこから検索インデックスを構築できます。探している特定の用語が項目内に存在することがわかっている場合は、SOQL よりも SOSL のほうが迅速に検索できることがあります。ただし、各 Apex トランザクションのガバナ制限は、1 つのトランザクションにおける複数の SOSL 検索では 2,000 件ですが、SOQL クエリでは 50,000 件です。そのため、レコードを 2,000 件以上取得する必要がある場合は、SOQL のほうが適しています。
Force.com クエリオプティマイザー
Salesforce ではマルチテナントアーキテクチャが使用されるため、支援なしにデータベースシステムのオプティマイザーで Salesforce クエリを効率的に最適化することはできません。そのため Salesforce プラットフォームには、独自のクエリオプティマイザーが搭載されています。このオプティマイザーはインデックス付き項目を活用して、そのクエリにとって最も効率的な実行プランを作成し、データベースシステムのオプティマイザーが Salesforce クエリの効果的な実行プランを生成できるようにします。
Force.com クエリオプティマイザーには、各インデックスのデータの分布に関する統計情報を示すテーブルが保持されています。このテーブルを基に事前クエリを実行して、インデックスを使用するとクエリが加速するかどうかを判断します。このオプティマイザーは、レポート、リストビュー、SOQL クエリとそれに抱き合わせた他のクエリの両方を処理する目的で自動生成されるクエリで機能します。
Apex の一括処理
一般に、Force.com プラットフォームで大規模なデータセットにクエリを実行して処理する最適な方法は、バッチ単位で非同期処理することです。Apex の一括処理を使用すれば、最大 5,000 万件のレコードにクエリを実行して処理できます。
Apex の一括処理はすべての使用事例で機能するわけではありませんが (たとえば、50,000 件以上のレコードを照会する必要がある Visualforce ページなどのように同期的に使用する場合は機能しません)、ツールキットに備えておくべき優れた手法です。
一括クエリ
大規模なデータセットを効率的に照会するもう 1 つの方法が一括クエリです。一括クエリでは、最大 15 GB のデータを 15 個の 1 GB のファイルに分割して取得できます。結果が 1 GB を超える場合は、応答を完成させるためのファイルが追加されます。
Bulk API クエリでは、query と queryAll の両方の操作がサポートされています。queryAll 操作では、merge または delete によって削除されたレコードも返されます。queryAll 操作ではまた、アーカイブ済みの ToDo レコードや行動レコードに関する情報も返されます。
一括クエリジョブにバッチを追加するときは、要求のヘッダーの Content-Type に、ジョブの作成時に指定したコンテンツタイプに応じて、text/csv、application/xml、application/json のいずれかを指定する必要があります。バッチに指定する実際の SOQL ステートメントは、平文テキスト形式で表されます。
一括クエリの処理方法
一括クエリを処理すると、Salesforce でクエリの実行が試行されます。標準のタイムアウト制限 (2 分) 内にクエリが実行されなければ、ジョブに失敗し、QUERY_TIMEOUT エラーが返されます。この場合は、単純なクエリに書き換えて、バッチを再送信してください。
クエリが正常に実行されると、Salesforce で結果の取得が試行されます。結果が 1 GB のファイルサイズ制限を超えているか、取得に 5 分以上かかる場合は、処理が完了した結果がキャッシュされ、次の試行が行われます。試行回数が 30 回を超えると、ジョブが失敗し、[Retried more than thirty times (試行回数が 30 回を超えました)] というエラーメッセージが返されます。この場合は、PK Chunking ヘッダーを使用して、クエリの結果を小さなチャンクに分割することを検討してください (PK Chunking については、後続の単元で詳述します)。試行に成功すると、結果が返され、7 日間保存されます。
スキニーテーブルの使用
たとえば、コーディングのベストプラクティスに従い、Salesforce カスタマーサポートの助けを借りて必要な場所にカスタムインデックスを配置したのに、依然としてパフォーマンスの問題が発生しているとします。レポートやダッシュボードのタイムアウトに関する苦情がユーザーから寄せられ、Visualforce ページからコールされる SOQL の動作が次第に遅くなっています。何が何でもパフォーマンスを改善させる必要がある場合には、特別の強力な解決策があります。スキニーテーブルです。
スキニーテーブルとは、Force.com プラットフォームのカスタムテーブルで、Salesforce の標準またはカスタムの基本オブジェクトにある項目のサブセットで構成されます。Force.com には必要に応じて複数のスキニーテーブルを設定でき、完全に透過的な状態で維持されます。
スキニーテーブルは Salesforce の基本オブジェクトよりも行が狭く、スキャンするデータが少ないため、データベースの取得ごとに Force.com がより多くの行を返すことができ、大規模なオブジェクトから読み込む場合のスループットが向上します (下図を参照)。
また、スキニーテーブルには論理削除された行 (ごみ箱内にある isDeleted が true のレコード) は含まれないため、通常はテーブルの容量が減少します。基本テーブルのカスタムインデックスも複製され、基になるデータベースのクエリで生じるテーブル結合が減少するため、通常はパフォーマンスが向上します。
スキニーテーブルによってクエリが加速する一例として次のような場合が挙げられます。年間レポートまたは年度累計レポートを作成するときに、01/01/16 ~ 12/31/16 のような日付範囲を使用すると反復計算が必要となり、コストがかかります。代わりに、スキニーテーブルに Year 項目を追加すれば、Year = '2016' で絞り込むことができます。
Force.com プラットフォームで基本オブジェクトとスキニーテーブルの行が自動的に同期されるため、常に最新のデータが表示されます。クエリの実行時に Force.com プラットフォームが、スキニーテーブルの使用が適していると思われる状況を判断するため、レポートを修正したり、Apex コードや API コールを作成したりする必要はありません。
スキニーテーブルが役立つのは特に何百万件ものレコードがあるテーブルです。スキニーテーブルは、カスタムオブジェクト、および取引先、取引先責任者、商談、リード、ケースの各オブジェクトに作成できます。そして、レポート、リストビュー、SOQL のパフォーマンスを向上させることができます。
スキニーテーブルは、パフォーマンスの問題を是正する便利な手段です。ただし、すべての使用事例に対応するとは限らず、効率的なインデックスを付けた Salesforce の基本オブジェクトからの読み込み以上のパフォーマンスの改善は見込めないことがあります。ビジネスプロセスに制限または負荷がかかることがあるため、副次的影響についても理解しておく必要があります。
以下は、スキニーテーブルを実装する場合、事前に考慮しておくべき事項です。
-
スキニーテーブルは必要最小限である。パフォーマンスを最適なものにするために、特定のビジネス使用事例の遂行に必要な最低限の項目セットのみで構成されます。後々、レポートまたは SOQL クエリに項目を追加することにした場合は、Salesforce カスタマーサポートに連絡してテーブルを作成し直す必要があります。
-
Full Sandbox の場合: スキニーテーブルは Full Sandbox 組織にコピーされます。他の種類の Sandbox では、スキニーテーブルは Sandbox 組織にコピーされません。Full Sandbox 以外の Sandbox で本番用スキニーテーブルを有効にするには、Salesforce カスタマーサポートにお問い合わせください。
-
スキニーテーブルは基盤となる Force.com データベースのカスタムテーブルである。基本オブジェクトに見られるようなメタデータの動的な柔軟性はありません。データ型を変更すると (数字項目からテキスト項目に変更した場合など)、スキニーテーブルが無効になり、Salesforce カスタマーサポートに連絡して新しいスキニーテーブルを作成し直す必要があります。
大量データを伴う検索を迅速に行うための数種類のツールを習得したところで、データの読み込みに関する次の単元に進みましょう。
リソース
- Salesforce 開発者: Long- and Short-Term Approaches for Tuning Force.com Performance (Force.com のパフォーマンスを調整する長期的および短期的なアプローチ)
- Salesforce 開発者: 非常に大きい SOQL クエリの処理
- PDF: Force.com SOQL Best Practices: Nulls and Formula Fields (Force.com SOQL ベストプラクティス: NULL 項目と数式項目)
- Salesforce 開発者: 大量のデータを使用するリリースのベストプラクティス/SOQL と SOSL
- Salesforce 開発者: 一括クエリの処理方法
- Salesforce 開発者: 大量のデータを使用するリリースのベストプラクティス
- Salesforce 開発者: 一括クエリサンプルの説明
- PDF: Query & Search Optimization Cheat Sheet (クエリおよび検索最適化のための早見表)