2011-09-13 8 views
2

場所に基づいてストアレコードを取得するためのクエリを最適化しようとすると、私は何か変わった(私は思う)にダンプし、大量のデータセットを取得するのはCPU時間を要します。大規模なデータセットを取得して繰り返し、何が問題なのですか?そして、なぜadmin log/appstasの違いがありますか?

基本的に私はユーザーの位置3000m以内に店舗を見つけるために反復処理が必要な> 1000件のレコードを持っています。管理コンソールでは非常に高い数字があります。

これは、1000レコードを取得するためのいくつかの興味深い数字をもたらしたいくつかのデータストアテストにつながります。

私は私に6つのテストメソッドを持っているが、(生産)別に実行し、管理コンソールとAppstatsのからCPU時間を取り、それがこのの結果:

ここ
r = db.GqlQuery("SELECT __key__ FROM StoreRecords").fetch(1000) 
    # appstats: real=120ms cpu=182ms api=845ms 
    # admin console: 459ms 1040cpu_ms 845api_cpu_ms 

    r = db.GqlQuery("SELECT __key__ FROM StoreRecords").fetch(100) 
    # appstats: real=21ms cpu=45ms api=95ms 
    # admin console: 322ms 134cpu_ms 95api_cpu_ms 

    r = db.GqlQuery("SELECT * FROM StoreRecords").fetch(1000) 
    # appstats: real=1208ms cpu=1979ms api=9179ms 
    # admin console: 1233ms 10054cpu_ms 9179api_cpu_ms 

    r = db.GqlQuery("SELECT * FROM StoreRecords").fetch(100) 
    # appstats: real=57ms cpu=82ms api=929ms 
    # admin console: 81ms 1006cpu_ms 929api_cpu_ms 

    r = model.StoreRecords.all().fetch(1000) 
    # appstats: real=869ms cpu=1526ms api=9179ms 
    # admin console: 1061ms 9956cpu_ms 9179api_cpu_ms 

    r = model.StoreRecords.all().fetch(100) 
    # appstats: real=74ms cpu=86ms api=929ms 
    # admin console: 97ms 1025cpu_ms 929api_cpu_ms 

を私は1000年、最大で取りますレコードを取得する必要がありますが、すべてを取得する必要があります(約4-5000)。

私の質問は以下のとおりです。

  1. は本当に、ほぼ20(10054cpu_ms + 9179api_cpu_ms)秒かかる1000年、レコードのフェッチすべきか?
  2. なぜAppstasと管理コンソールの時間に違いがありますか?私のクォータに対して計算されるのは何ですか?

フェッチされたレコードをprotobufとしてmemcacheにプッシュすると、これを簡単に回避できます。しかし、私はアプリケーションの使用量が多いことと、アプリケーションと管理コンソールとの時間の違いが気になります。

ボーナス質問: 9179api_cpu_ms 1000件のレコードをフェッチ常に結果ということに来るどのように?

答えて

1

多くのレコードを取得するのに多くのリソースが必要なのはなぜですか?これはO(n)プロセスなので、リクエストごとに行うべきではありません。

  1. どのCPU時間を使用するかは、記録の性質によって異なりますが、この結果は驚くべきことではありません。それはほぼ20 のCPU秒であり、壁時計秒ではないことに注意してください。また、新しい請求モデルがロールアウトされると、データストア操作とインスタンス時間に課金されることになります。これは最適化する必要があります。
  2. 管理コンソールには、あなたが請求した権威ある数字が表示されます。 appstatsの数値は、API呼び出し中に費やされた時間だけをカウントし、独自のコードを実行するのに費やされた時間ではないため、低くなります。

レコードのセットが小さく静的な場合は、それらを毎回フェッチするか、memcacheに格納するのではなく、インスタンスメモリにキャッシュする必要があります。より大きい動的な場合は、GeoModelのようなものを使用して地理的なクエリを実行し、関連するレコードのみを取得する必要があります。

1000レコードを取得するのは、データストアのアクセスコストがどのように表現されるため、常に同じ量のAPI CPU時間がかかります。実際には時間がかかるわけではありません。新しいモデルでは、別の請求可能な操作に分割することでこれを修正しています。

+0

ありがとうございます。私はたくさんのquiresを得ることは時間がかかることを理解する。 GeoModelをチェックします。キャッシュに入れる前に最初のリクエストに長い時間(管理コンソールでは赤色)がかかるという欠点はありますか? googleのバックエンドはこれらのインスタンスをスケーリングの点でどのように扱うのですか? – fredrik

+0

@fredrik欠点は、ユーザーを待たせることです。ロード要求だけが遅い場合、スケーリングには影響しません。ただし、ウォームアップハンドラを調べる必要があります。これにより、少なくとも一部の時間に、最初のユーザー向きのリクエストの前にこのデータを読み込むことができます。 –

関連する問題