2013年3月22日金曜日

GAE/J + JDO で Single Property Index を作らせない

表題のとおりですがようやくたどり着いたのでメモ。

サイト自体にも書いていますが、#f1yosou Google App Engine/Java (以下 GAE/J)を使っています。もともと3年前(もう3年になりますか・・・)にはじめたときには結構余裕だったのですが、Googleさんの緩やかな締め付けwで無料での利用部分がどんどん制限されてきて、最初のころにはタコなコードを書いていても余裕があったのですが、最近はかなり厳しくなってきています。これまでもそれなりに使用量を抑制しつつなんとかごまかしてきました。

そんな最近の #f1yosou サイトのもっとも厳しい項目は、Datastore Write Operations の項目です。これは文字通り Entity を Datastore に書き込むと消費するやつですね。これが特に #f1yosou タグのついたツイートを解析して結果を書き込む処理を経るとかなり消費されます。処理としては
  • 該当するツイートの保存
  • 同一の予想をしたツイートのカウントを行い、その結果を保存
ということをしていますが、どうも後者の処理がかなりの書き込みを生じているようです。そもそもこの Datastore Write とは Entity を1つ書き込むと1回なのか?というところから調べ始めたところ、以下の記事がよくまとまっておりました。
EntityのPropetryの構成よって、Datastore writeの数は変わる!
なるほど。そもそもプロパティの数によって増えるのもあるんですがそれは実際に値をしまってるので仕方ないとして、各プロパティについて勝手に自動的に作成される Index の書き込みのほうが問題ですね。そもそも使ってないのに昇順・降順で2つ作られてるみたいですし。これを削減できればだいぶ効きそうです。ただし
Single Property Indexを作らないとComposite Indexも作成されない?
という考慮点もあるみたいなのでなんでもかんでも削れるわけではないようです。

と、ここまできて JDO ではどうやって指定するんだろう・・・と思って調べてもなかなかでてきません。いろいろググっていたらようやく Entity#setUnindexedProperty() なるものがでてきました。しかしこれも Low Level API。。。

まあそれでもいいか、と思ってやり方を探っていたらとうとう発見しました。まんまの質問がありましたw なぜこれに最初に行き当たらなかったのか不思議なぐらいそのままです。要するに
@Extension(vendorName = "datanucleus", key = "gae.unindexed", value="true")
を索引がいらないプロパティにつけるだけです。あら簡単。

早速実験してみます。1回処理すると以下のようになる Entity を用意しました。
 このクラス定義のところにある correct というプロパティに Index を作らないようにします。
 @Persistent
 @Extension(vendorName = "datanucleus", key = "gae.unindexed", value="true")
 private Boolean correct;
とすると、
のように2減りました。この2というのが昇順と降順で1つずつの結果のようです。
#上では赤丸がついている Entity にのみ処理をしました。

これで削減できるかな?

0 件のコメント:

コメントを投稿