【问题标题】:eliminating unnecessary database hits in django消除 django 中不必要的数据库命中
【发布时间】:2010-12-07 13:43:45
【问题描述】:

我想在使用 django 时减少实际的数据库命中,所以我创建了这个人工示例来概述问题。模型如下所示:

class Car(models.Model):
    name = models.CharField(max_length=10)
    user = models.ForeignKey(User)

在我看来,我想做这样的事情:

def cartest(request):
    cars = Car._default_manager.filter(user__username__exact='michael')[:5]
    first_car_name = cars[0].name
    another_car = cars[1]
    return HttpResponse(len(connection.queries))

所以我想从数据库中选择 5 个条目,对第一个做一些事情,然后对第二个做一些事情(记住这是一个人为的例子)。必须有某种方法可以做到这一点,而不会两次访问数据库,对吧?

谢谢, 迈克

【问题讨论】:

  • 啊,当我迭代“汽车”而不是尝试下标它时,似乎是在做我想做的事。

标签: sql django orm


【解决方案1】:

啊,想通了……这样就达到了预期的效果。问题是下标查询集而不是迭代它(或调用列表(查询集))。只访问数据库一次:

def cartest(request):
    cars = list(Car._default_manager.filter(user__username__exact='michael')[:5])
    first_car_name = car[0]
    another_car = car[1]
    return HttpResponse(len(connection.queries))

【讨论】:

  • 实现相同效果的更简单方法是简单地执行cars = list(Car._default_manager.filter(user__username__exact='michael')[:5]) - 在查询集上调用list 会对其进行评估。
  • 完美。更新我的答案。谢谢。
【解决方案2】:

此时您是否真的遇到了性能问题,或者您只是担心应用程序的未来可扩展性?

正如 Tim Wardle previously 所说的那样,不要试图过早地进行优化。利用 Django 为您节省的开发时间,您可以更快地推出应用程序。一旦你有了用户,然后看看你的瓶颈并尝试修复它们。

但是,如果您确实遇到了性能问题,我会看看查询集对update multiple objects at once 和获取数据in bulk 的能力。

据我所知,至少有 one rejected ticket 可能会对您有所帮助(取决于您的数据库系统)。

您总是可以将 Django 的 ORM 取出并用 SQLAlchemy 替换它。

This post(可能是 NSFW)有一些关于制作高性能 Django 应用程序的建议。

James Bennett 对一般缩放有一些好处,其中一些是关于 ORM performance

【讨论】:

  • 谢谢,没有性能问题...当您只需要 1 次时,我只是觉得 2 或 3 次数据库命中是错误的。弄清楚如何获得所需的效果,请参阅上面的评论。谢谢,-迈克
猜你喜欢
  • 1970-01-01
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多