0

次のようなものがあります。

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 オーバーヘッドを削減するための、よりクリーンなオプションはありますか?

4

1 に答える 1

0

繰り返しますが、モデルを見ずして肯定することはできませんが、このセットアップを Django 1.7 でテストしたところ、2、3 のクエリだけですべてを取得できるはずです。

pages = Page.objects.prefetch_related("sections","sections__tiles").all().select_related(‌​'sections__tiles__author')
for page in pages:
for section in page.sections.all():
    for tile in section.tiles.all():
        print tile.author
于 2014-09-25T22:22:41.897 に答える