app engine ja night kansai 2「Query & Index」メモ
bpstudy33と同日に開催されたajnk2について、@bufferings さんのUST録画をみながら理解したことをメモ。Cacooで描かれたという図がすごく見やすく、わかりやすかったです。bufferingsさんのブログにpdfとustへのリンクあり。
#appengine ja night in kansai 2 ( #ajnk2 ) を開催しました! - bufferings
おさらい
Bigtableからのデータ取得
三種類の取得。a,b1,b2,b3,cとエンティティがある場合
- Readは1エンティティの取得。(aのみ)
- Prefix Scanはb1〜b3のような前方スキャン
- Range Scanは b〜dのような範囲スキャン
Datastoreからのデータ取得
- Get ー KeyのAppID + Path情報から取得
- (参考)Batch Get 複数のkeyでまとめてEntityをGet
- Query ー Kind、Filter, Sort Orderにより結果リスト(=Index)から取得
- Indexは、使用するすべてのクエリに大して必要。RDBのような問い合わせ時の計算、集約、Joinは不可。取得はエンティティ全部、もしくはキーのみのいずれか。Entityを更新すると関係するインデックスが更新される。
Query
- Queryの構成
- Kindを指定
- 0個以上のフィルタを指定(=, <=, <, >, >=, !=, IN)
- 0個以上のソート順を指定(ASC, DESC)
- KindlessQueryはKindを指定しない特別なクエリ
- 制約(クエリの仕組みを知れば制約の理由がわかる)
- フィルタ/ソートには、プロパティ自体が存在してなければならない
- 不等式フィルタが使用できるのは1つのプロパティのみ
- 不等式フィルタで使用されているプロパティはほかのソート順よりも先にソートする
Index
- インデックスには3種類ある。
- Kind Indexー自動で作成される。特定のKindの全Entityを取得するときに使う
- Single Property Indexー自動で作成される。Kind IndexにPropertyName とPropertyValueが入っている。昇順と降順それぞれのインデックステーブルが作成される。
- 等式ならPrefixスキャン
- 不等式+不等式ならRangeスキャン
- カスタムインデックス
Merge Join
- 複数のプロパティであっても、等式フィルタのみならCustom Indexを定義しなくてもQueryを実行できる
- Single Property Indexをzig-zagアルゴリズムによりマージしながら検索する
- ただし、データ量が多いとエラーになってしまう
- Custom Indexが定義済みならMerge JOINは行われない
Key Only Query
- キーだけを返すクエリ。 quotaを節約できる。
- 例えばエンティティ削除の時はキーだけでよい
Queries on Key
- キーに対してのフィルタ。(等式はget()でよいので、不等式)
- キーの降順ソートにはCustom Index定義が必要
Kindless Query
- Kindを指定しないQuery
- AncestorとKeyフィルタのみ指定可能(JavaはAncestorのみ
Not-Equalフィルタ(!=)、INフィルタ
- NotEqualフィルタは内部的には不等式フィルタの結果をマージするので、不等式フィルタと同じ制約あり
- INフィルタは複数の等式フィルタをマージする
- どちらも複数のQueryを実行するので通常のクエリより遅い
Ancestor Query
- EntityGroupの祖先を指定してEntityを取得するQuery
- Kindless Ancestor Query(Kind指定なし。Javaは不可)
- Ancestor Query (Kind 指定あり。)
- -
MVP(Multi Value Property)
感想
Slim3のDatastoreまわりのメソッドをひととおり調べてて、なんでこうなってるんだろうと思うことが多々あったのですが、今回ちゃんと仕組みを知れたことで、腑に落ちたことがたくさんありました。ありがとうございました。