使用带有许多参数的 select_related 和 prefetch_related

using select_related and prefetch_related with many arguments

我对django比较陌生,我正在使用select_related()prefetch_related() 在 Django 中减少我对数据库的访问。

这是我的 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.36 毫秒内执行 42 次查询,添加这些后,它减少到 7.91MS10次查询,看着这个数据,我觉得那些功能真的很棒

所以我的问题是:使用这两个函数有什么缺点吗?不应该一次性加入这么多桌吗?

简单回答

不,没有缺点

真实答案

预取相关在 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)