1

我对 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 个查询,查看这些数据,我认为这些功能真的很棒。

所以我的问题是:使用这两个功能有什么缺点吗?我不应该一口气加入这么多桌子吗?

4

1 回答 1

2

简单的答案

不,没有缺点

真实答案

预取相关在 python 端进行连接。大多数时候这很好,但总是配置文件。Prefetch当您需要进一步调整数据库访问时,您可能还会发现该对象非常有用。

Select related 会执行您所期望的操作(它会创建连接语句并将其刷新到数据库中),并且如果时间合适,它将表现得非常好。

在扩大规模时,连接可能会成为更大的障碍——您可能希望通过非规范化、实现缓存层、按资源类型分离调用等来改变您的数据模型。

边注

您将希望开始将这些更大的查询放入您的模型管理器中,以便视图可以调用一个方法,您可以在幕后进行调整。

例如(注意,使用查询集子类等有更新的方法。)

# 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)
于 2017-06-05T20:31:56.973 回答