有没有办法通过让它只在django的ORM中读取来更快地选择?

时间:2010-09-19 04:27:12

标签: django orm

如果我只是获取用户列表,并且我无意更新此列表,我是否可以选择将查询标记为“只读”?

原因是,我知道大多数ORM都会对返回的行进行某种更改跟踪。因此,如果我事先知道我不需要更新任何内容,那么我是否可以告诉ORM将结果集标记为只读,这很奇怪。

3 个答案:

答案 0 :(得分:2)

  

如果我只是获取用户列表,并且我无意更新此列表,我是否可以选择将查询标记为“只读”?

AFAIK没有办法解决这个问题。我想知道是否有人认为/不知道。

  

原因是,我知道大多数ORM都会对返回的行进行某种更改跟踪。因此,如果我事先知道我不需要更新任何内容,那么我是否可以告诉ORM将结果集标记为只读,这很奇怪。

请问这个要求的原因是什么?感觉就像我过早优化一样。如果你进行一些分析发现某个特定查询的性能很差认为可以通过使查询集读取来改进 只有,然后这个问题开始发挥作用。不太可能,恕我直言。

答案 1 :(得分:1)

您可以保留查询集,只要对其进行评估,就不必再次进行查询。您甚至可以将此附加到请求中。

示例:

# in the view, a decorator, or middleware
request._my_users = Users.objects.all()
request._my_users[:]

# Later reference request._my_users

答案 2 :(得分:0)

ORM不需要跟踪提取的行,而是通过主键标识行来确定是否插入或更新(如果没有使用save()设置force_insert或force_update)。

谁可以在这里阅读:http://docs.djangoproject.com/en/1.2/ref/models/instances/#how-django-knows-to-update-vs-insert

这就是说,没有必要甚至不可能使用“只读”模型,因为它不会产生任何性能提升。

如果你想进行优化,你可以尝试一些步骤(但只有很小的改进,所以你可能不应该在真正需要之前进行优化)。

例如,请致电querySet.exists()querySet.count()代替(bool)querySet resp。 len(querySet) if(且仅当)您之后没有从查询集中读取。否则,不要使用exists()/ count(),因为它会产生一个额外的查询,而在后一个缓存中,查询集的实际读取是免费的,因为它已经被缓存了。

另一个措施是使用only()和defer()将SELECT限制为您实际需要的字段,并选择select_related()来预取外键关系,如果您知道将需要它们。如果您拥有包含许多关系和列的较大模型,则可以显着提升性能。