我有一些看起来像这样的东西:
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
这会针对初始查询命中 SQL 层一次,然后在每个循环 (n+1) 中命中一次。然而,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 开销?