皆さんクエリ返ってきてますか? 前回の記事では、讃岐がインデックスが有効に働いているかどうかを確認することができるクエリパフォーマンスのフィードバック機能を紹介しました。この機能を利用することで、SOQLのパフォーマンスのチューニングがより効果的に行えることでしょう!
今回は、大量データを扱う際、パフォーマンスを上げる為に、効果的なインデックスを貼る以外にもいくつか方法があるので、その1つを紹介したいと思います。
おっと、その前に、以下の質問をはい、いいえで回答してみてください。
LDV(大量データ)マスターチェッカー
- インデックスを意識して外部IDを使用したことがある。
- カスタムインデックス作成をサポートに依頼したことがある。
- 2カラムカスタムインデックス作成をサポートに依頼したことがある。
- 複合キーやNULL条件を項目自動更新や数式を使って作ったことがある。
- 過去/履歴データをパージ(HARD DELETE)するバッチApex等を作成したことがある。
- 過去/履歴データをAWSなど、外部ストレージにアーカイブする仕組みを構築したことがある。
- CanvasやHeroku等を利用してそのデータを参照できるUIをインテグレーションしたことがある。
- 「Force.com のマルチテナントアーキテクチャ」という記事を読んで理解した。
- スキニーテーブルを利用したことがある。
- パーティショニングを意識して、ディビジョンを利用したことがある。
全て、「はい」と答えたあなた、もう立派なLDV(大量データ)マスターです!!早速画面右上の「クラウドやるならテラスカイ。求む!Salesforce開発エンジニア」のバナーをクリックしましょう!
この質問の9番目にでてくる、「スキニーテーブル」を今日は、紹介したいと思います。 スキニーテーブルの効果を理解する為には、まずForce.comのマルチテナントアーキテクチャを理解せねばなりません。
Force.comマルチテナントアーキテクチャ
以下は、Force.comが採用しているデータベーススキーマです。 左のメタテーブルには、普段みなさんがeclipseや変更セットを使ってデプロイしているオブジェクトの定義やカスタム項目などの情報が格納されています。真ん中のデータテーブルに、実際の値がはいっていますが、MT_Clobsというところには、ロングテキスト型の文字などが格納されています。右にあるピボットテーブル類には、インデックスやリレーションなどの情報が格納されています。
注目すべきは、真ん中にある魔法のボックスと呼ばれるMT_Data(データテーブル)です。 このテーブルのスキーマは、どんな型のデータでも受けれるように可変長文字列型でおそらく最大800項目ぐらいまであるのではないでしょうか。そしてこの中に、「あらゆる組織とあらゆるオブジェクト」のデータが格納されています。
例えば、組織Aの顧客情報と商品情報。組織Bの取引情報のオブジェクトがある場合はというと、、、
なんということでしょう!このような感じで、1つのテーブルに2つの組織と3つのオブジェクト情報が格納されている状態になっています。
しかもこのテーブルには、論理削除レコードも含まれています。これをみるだけで、安易なフルスキャンを想定したSOQLを書くことを考えなおすことになるのではないでしょうか。
一般的にデータベースでは、1回のブロックリードで取得できるレコード数が少ない場合、複数回のブロックリードが必要になり、ストレージ効率が悪くなるので、インデックスが効いているのに結果としてパフォーマンスがでにくい状況になることがあります。項目が多いとレコード長が長くなるので、オブジェクトの項目数を減らせばよいような気にもなりますが、このようなマルチテナントアーキテクチャの構造の特性上、自組織のSOQLやオブジェクト構成等には依存せず、ブロックリード数が多くなることもまれにあるのが事実です。
このような状況下で、効果を発揮するのが、スキニーテーブルです。では、その説明にいきましょう。
スキニーテーブル
スキニーテーブルとは、
スキニーテーブルとは、簡単に言うとこのようなものです。
- ・指定した一部の項目だけで構成されたテーブルで、実テーブルからデータがリアルタイムで同期されます。(ゴミ箱以外)
- ・大量データが格納されているオブジェクトに対するクエリーの性能を上げることができます。
- ・クエリー実行時、スキニーテーブルにアクセスされるか、実テーブルにアクセスされるかは、Force.comのクエリーオプティマイザが自動で決めてくれます。
作成方法
- ・項目を100個以内で決める。(少ない方がよい)
- ※数式不可(参照している項目が全てはいってればOK)
- ※主従、参照項目はOK(参照先もスキニーテーブルがあれば、スキニーテーブル通しのJOIN)
- ・サポートに依頼する。(有効性のチェックあり)
作成時注意点
- ・カスタムインデックスの貼られている項目を、スキニーテーブルの項目として指定しても、別途インデックスの作成依頼が必要
- ・Sandboxで使う場合も、別途依頼する必要がある(コピーされない)
- ・項目を追加する場合は、スキニーテーブル再作成の依頼が必要。
- ・項目の定義(型など)を変えると、スキニーテーブルが無効化される。
- ・SystemModstampは、使えない。LastModifiedDateで代用できないか検討する。
なぜパフォーマンスが上がるのか?
では、なぜスキニーテーブルを使うとパフォーマンスが上がるのかですが、以下のような理由があります。
- ・項目数が限定されている。
- ・特定組織の特定オブジェクトのデータしか格納されていない。
- ・論理削除データは含まない。
その結果、
- ・テーブルジョインが減る。
- ※標準オブジェクトの場合は、標準項目とカスタム項目は、別テーブルで管理されているそうで、「Select StageName,Field__c From Opportunity」は、裏では、テーブルジョインが発生していることになります。スキニーテーブルではこれが1テーブルに格納されます。
- ・レコード長が短いので、1ブロックで読めるレコード数が多くなる。
- ・より多くのレコードをキャッシュできる。
- ・総レコード数が少ないので、フルスキャンが使える。
となります。ぜひSOQLの実行計画REST APIと共にパフォーマンス・チューニングの手立てとして活用してみてください。
最後に
どんなプラットフォームでも長所と短所があります。短所を非難するのではなく、それらを理解して、代替案や回避方法を提案して、長所を有効活用させてあげることこそがSalesforceコンサルタントの価値かと思います。LDV(大量データ)マスターチェッカーで全てチェックが入るようなマスターを目指してがんばりましょう!!
参考資料
Force.com のマルチテナントアーキテクチャ https://developer.salesforce.com/page/JP:Multi_Tenant_Architecture
大量テ?ータを扱う際のクイックTips http://www.slideshare.net/DeveloperForceJapan/tips-30066265
知られざる「マルチテナントアーキテクチャ」 http://www.publickey1.jp/blog/09/1saas.html