私が取り組んでいる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()
と
ndb
のdb
を使用してみましたが、結果はほとんど同じです。だから、今私は何をすべきか分からないのですか? n
の半分のパフォーマンスを10000のオーダーで得る方法はありますか?エンティティを単一のフィールドに単純化しても、パフォーマンスは低すぎます。私はペイロード全体を約1MBに圧縮すると予想しています。 1分に1MBをダウンロードすることは明らかに容認できません。 私はこの問題をライブで見ていますが、パフォーマンステストではリモートAPIを使用しています。私の質問はSO:Best practice to query large number of ndb entities from datastoreのこの質問に似ています。彼らは解決策を見つけるように見えなかったが、それは4年前に尋ねられた、おそらく1つが現在かもしれない。
このリクエストのログには何が表示されますか? –
行をフェッチした後、何をしたいですか? – Vincent