次のようなものがあります。
pages = Page.objects.prefetch_related("sections","sections__tiles").all()
for page in pages:
for section in page.sections.all():
for tile in section.tiles.all():
print tile.author
# more stuff to build each page
これは、最初のクエリで 1 回、次にループ (n+1) ごとに 1 回、SQL レイヤーにヒットします。ただし、SQL クエリの最適な数は 1 + (一意の作成者の数) です。
「著者」の単純なハッシュベースのキャッシュを実装し、読み込み時間を劇的に短縮しました。
cache_author = {}
def author_cache(author_id):
author = cache_author.get(author_id, None)
if author:
return author
else:
author = Author.objects.get(id=author_id)
cache_author[author_id] = author
return author
pages = Page.objects.prefetch_related("sections","sections__tiles").all()
for page in pages:
for section in page.sections.all():
for tile in section.tiles.all():
print author_cache(tile.author_id)
# more stuff to build each page
でもごちゃごちゃした感じ。単一のトランザクション内の SQL オーバーヘッドを削減するための、よりクリーンなオプションはありますか?