我对django比较新,我在django中使用 select_related()和 prefetch_related()来减少对数据库的点击。
这是我的 views.py 文件的一部分:
topic = Topic.objects.filter(id=topic_id).select_related('followed_by')
questions = Question.objects.filter(topics=topic).prefetch_related('answers','question_comments','answers__created_by__userprofile','answers__answer_comments')
如果没有select_related和prefetch_related,则视图会在23.36MS 中执行 42个查询,并且添加了这些查询后,它会在7.91MS 中减少到 10个查询,查看此数据,我认为这些功能非常棒。
所以我的问题是:使用这两个函数有什么缺点吗?我不能一次加入这么多桌子吗?
答案 0 :(得分:1)
不,没有缺点
预取相关在python端进行连接。大部分时间这很好,但总是有个人资料。当您需要进一步调整数据库访问时,您可能还会发现Prefetch
对象非常有用。
选择相关会执行您期望的操作(它创建连接语句并将其刷新到数据库),并且如果时间的话,它将表现得非常好。
在扩展中,连接可能变得更加阻碍 - 您可能希望通过非规范化,实现缓存层,按资源类型分离调用等来改变数据模型。
您希望开始将这些较大的查询放入您的模型管理器中,以便视图可以调用方法,您可以在幕后调整。
e.g。 (注意,有更新的方法可以使用queryset子类等。)
# models.py
class QuestionManager(models.Manager):
def by_topic(self, topic):
return self.filter(topic=topic).prefetch_related('...')
# views
def my_view(request, *args, **kwargs):
# get the topic however
topic = get_topic(kwargs.get('topic')
Question.objects.by_topic(topic)