通过select_for_update记录优化两个ForeignKeys的访问

时间:2013-03-15 08:43:14

标签: django query-optimization

我有一个像这样的Django(1.4.2)数据模型:

class CoreData(models.Model):
    cdid = models.AutoField(primary_key=True,editable=False)
    atr1 = # whatever
    atr2 = # whatever

class EnvironData(models.Model):
    cdid = models.ForeignKey(CoreData)
    # etc

class TransactionData(models.Model):
    edid = models.ForeignKey(EnvironData)
    # etc

我需要一个原子事务,我在其中更新etc事务数据:

tdo = TransactionData.objects.select_for_update().get(etc=criteria)
# process transaction
# modify tdo object
tdo.save()

到目前为止,这么好。但是,在process transaction期间,我需要检查CoreData.atr1CoreData.atr2

如果我通过tdo.edid.cdid.atr{1,2}访问那些,那么我的理解是我将有一个额外的读取数据库查询,因为Django获取丢失的数据。 (说实话,我不是100%肯定它只是一个;也可能是两个 - 甚至六个但我会怀疑。)

另一方面,如果我将select_related()select_for_update()结合起来,我不仅会锁定不需要(也不应该)锁定的数据,我还会为{{1}创建开销}}

第三种方法可能是通过独立查询(与tdo.save()无关)获取数据,如果使用tdo,该查询将保证是单个数据库查询。另外,它可以使用select_related()

我认为最后一种方法效率最高,因为查询可以从values() EnvironData我已经拥有edid的对象开始。

我的观点是否合理?还有更好的方法吗?

更新:完全可以独立访问tdo.edid_id,甚至可以在交易期间进行更改,因为它们彼此独立,并且不需要他们维护整个交易的价值。 (谢谢@Uszy Wieloryba)

1 个答案:

答案 0 :(得分:0)

如果您的# process transaction取决于CoreData.atr1CoreData.atr2,则可能会锁定它们。