N+1 選択の問題を回避するために、Google App Engine が JOIN をサポートしているかどうかを暗黙のうちに尋ねていると思います。
Google App Engine は JOIN を直接サポートしていませんが、ReferencePropertyone to many relationship
を使用して定義できます。
class Author(db.Model):
name = db.StringProperty()
class Book(db.Model):
title = db.StringProperty()
author= db.ReferenceProperty(Author)
特定のシナリオでは、2 つのクエリ呼び出しで、最初の呼び出しで作成者を取得します。
author = Author.all.filter('name =' , 'fooauthor').get()
2 つ目は、特定の著者のすべての本を検索します。
books = Book.all().filter('author=', author).fetch(...)
JOIN を使用する一般的な SQL クエリと同じ結果を得ることができます。
N+1問題は、たとえば、100 冊の本をそれぞれの著者名とともに取得する場合に発生する可能性があります。
books = Book.all().fetch(100)
for book in books:
print book.author.name
この場合、1 + 100 のクエリを実行する必要があります。1 つは本のリストを取得するため、100 は著者の名前を取得するためにすべての著者オブジェクトを逆参照するためです (このステップはbook.author.name
ステートメントで暗黙的に実行されます)。
この問題を回避するための一般的な手法の 1 つget_value_for_datastore
は、特定の本の参照先の著者のキーを逆参照せずに取得する方法 (つまり、データストア フェッチ) を使用することです。
author_key = Book.author.get_value_for_datastore(book)
このトピックに関する素晴らしいブログ投稿がありますので、ぜひお読みください。
このメソッドは、author_key
リストから始めて、データストアから著者オブジェクトをプリフェッチし、それぞれを適切なエンティティ ブックに設定します。
このアプローチを使用すると、データストアへの多くの呼び出しが節約され、実質的に* N+1問題が回避されます。
* 理論的には、100 人の異なる著者によって書かれた 100 冊の本がある本棚では、データストアを 100+1 回呼び出す必要があります
あなたの質問に答える:
- Google App Engine は熱心なフェッチをサポートしていません
- 恐ろしいN + 1問題を回避するのに役立つ手法(すぐに使用できるものではありません)があります