通过object.fk.id和object.fk_id查找外键的区别

时间:2018-08-30 09:51:45

标签: python django performance

我还没有在SO上找到这个问题。

在Django的对象模型中进行外键查找的以下两个变体之间是否存在速度差异?我只需要外键。

class A(models.Model):
    x = models.PositiveIntegerField(null=True)

class B(models.Model):
    a = models.ForeignKey(A, null=True, on_delete=models.CASCADE)
    y = models.PositiveIntegerField(null=True)

b = b.objects.last()

是更快还是相同?

b.a_id
b.a.id

编辑:实际上,我想我可以自己回答……第二个变体应该比较慢,因为它是从db创建整个对象的,对吧?

2 个答案:

答案 0 :(得分:4)

简单地说:是的,有一定的区别,b.a_idb.a.id快。

后者作为附加查询从数据库中检索整个a对象。 (您可以通过添加.select_related('a')来保存该查询,但是仍然不需要执行.a.id而不是.a_id。)

答案 1 :(得分:1)

  

在Django的对象模型中进行外键查找的以下两个变体之间是否存在速度差异?我只需要外键。

是的fk_id存储在数据库中。默认情况下(即,如果您不以一种或另一种方式.defer(..)该字段,则在实现查询时(例如,对象已加载)该字段将被加载。

.fk_id 不是,这不需要额外的查询。而.fk是,除非您通过.select_related(..).prefetch_related(..)加载它,否则将需要额外的查询。关系(如外键关系)被 lazyly 加载:如果查询self.fk.id,将首先获取.fk,从而产生一个额外的查询,然后您将获取{ {1}}从该对象开始(不需要额外的查询)。