2016-04-19 10 views
2

私が取り組んでいるPython GAEアプリケーションでは、ストレージからn行を取得する必要があり、n> 100のパフォーマンス問題が発生しています。ほとんどの場合、nが10000未満であることが予想されます。データストアからいくつかの行をすばやく取得する方法はありますか。

それでは、単純なモデルを考えてみましょう:

class MyEntity(ndb.Model): 
    field1 = nbd.StringProperty() 
    field2 = ndb.StringProperty() 
    #... 
    fieldm = ndb.StringProperty() 
    # m is quite large, maybe ~ 30. Stored strings are short - in the order of 30 characters or less 

私はいくつかのデータを使用してデータストアを埋め、プレーンfetch()を使用して本当に悪いパフォーマンスを持っています。私はすべてのフィルタを削除してから、いくつかのエンティティを取得しようとすると、パフォーマンスが非常に悪いように見えます(一般的なSQLデプロイメントの場合と比べて)。 SQLを使用していますが、フラットな行をダウンさせるだけで、パフォーマンスは向上します。ここに私が試したことがあります:

  • 最も簡単なアプローチMyEntity.all().fetch(n)。これは、nと直線的に比例します。私はそれがn = 1000のために7sを取ることを期待しなかった。
  • fetch()を合理的に使用すると、パフォーマンスがさらに低下します。私は1から1000の範囲の値を試しました。
  • Doing keys_onlyは、桁違いの改善をもたらします。
  • クエリを手動で実行すると(through ndb.Query)、フィールドを1つだけ取得すると、1.2のオーダーで小さな改善が得られます。
  • fetch_async(n)を実行して待機すると、まったく同じパフォーマンスが得られます。
  • ジョブをp部分に分割してからfetch_async(n/p, offset=...)を実行し、すべての先物を待機して結合します。最悪の場合、パフォーマンスは最高ですが、パフォーマンスは大幅に低下します。 fetch_page()

  • 似たような話は、私はまた、代わりにndbdbを使用してみましたが、結果はほとんど同じです。だから、今私は何をすべきか分からないのですか? nの半分のパフォーマンスを10000のオーダーで得る方法はありますか?エンティティを単一のフィールドに単純化しても、パフォーマンスは低すぎます。私はペイロード全体を約1MBに圧縮すると予想しています。 1分に1MBをダウンロードすることは明らかに容認できません。

    私はこの問題をライブで見ていますが、パフォーマンステストではリモートAPIを使用しています。私の質問はSO:Best practice to query large number of ndb entities from datastoreのこの質問に似ています。彼らは解決策を見つけるように見えなかったが、それは4年前に尋ねられた、おそらく1つが現在かもしれない。

  • +0

    このリクエストのログには何が表示されますか? –

    +0

    行をフェッチした後、何をしたいですか? – Vincent

    答えて

    1

    あなただけあなたが取得したデータで何をする必要があるかに応じて、より良いパフォーマンスを得ることができますProjection Queries

    +0

    多くのクエリを取得するとパフォーマンスが向上しますが、n〜10000行を取得するパフォーマンスを向上させる一般的なソリューションを探しています。 – Gleno

    1

    に見て、その後、モデルのフィールドのサブセットが必要な場合。たとえば、前述のように_asyncdocumentation hereを使用します。 _asyncはブロックされていないので、最初のデータバッチを処理している間に、最初のデータバッチを処理している間に、データのサブセット、たとえば最初の100を取り出し、次に100レコードのサブセットに_asyncを呼び出すことができます。あなたの歳差運動が終了するまでに、.get_result()を使用して2番目のバッチ結果を取得し、そのデータの処理を開始し、_async ...などを使用して3番目のバッチを呼び出します。

    関連する問題