【问题标题】:Lazy querysets in djangodjango 中的惰性查询集
【发布时间】:2019-06-29 11:35:53
【问题描述】:

这更像是一个效率问题。我的 django 网页运行良好,因为我没有收到任何错误,但速度很慢。话虽如此,除了这里,我不知道我还能在哪里问这个,所以这里是:

我正在开发一个销售仪表板。这样做时,我会一遍又一遍地访问相同的数据,我想加快速度。

例如,我的指标之一是赢得的机会数量。这将访问我的机会模型,整理出在过去 X 天内赢得的机会并进行报告。

另一个指标是被忽视的机会。也就是说,仍然报告为正在处理的机会,但在 Y 天内没有任何活动。此指标还访问我的机会模型。

我读到here 说查询集是惰性的,如果我正确理解了这个概念,这意味着我的实际数据库仅在最后才被访问。通常这将是一个理想的情况,因为所有过滤器都已到位,并且查询集只访问最少量的信息。

目前,我对每个指标都有一个单独的函数。所以,对于上面的例子,我有 compile_won_opportunities 和 compile_neglected_opportunities。每个函数都以这样的开头:

won_opportunities_query = Opportunities.objects.all()

然后我从那里过滤掉它。如果我正确阅读了文档,这意味着我正在多次访问同一个数据库。

我的网页加载时有明显的延迟。为了找出导致延迟的原因,我注释掉了不同的代码部分。当我为每个函数注释掉访问我的数据库的代码时,我的网页会立即加载。我最初的想法是在我的调用函数中访问我的数据库:

opportunities_query = Opportunities.objects.all()

然后将该查询传递给使用它的每个函数。我的理由是该数据库只会被访问一次,但显然 django 不能以这种方式工作,因为它对我的页面加载时间没有明显的影响。那么,在我冗长的解释之后,我怎样才能加快我的页面加载时间呢?

【问题讨论】:

  • 如果您添加.filter(..),您将创建一个 QuerySet。该查询集是惰性的,因为它不会立即触发查询,而是在您强制评估时(例如枚举查询集)。
  • 低效的数据库查询确实是 Django(和其他数据库支持的 Web 框架)中的常见瓶颈。通过优化执行数据库查询的方式和时间,通常可以显着提高性能。但是找到应用程序中的特定瓶颈是您必须自己做的事情。正如@ipaleka 所建议的,django-debug-toolbar 是一个非常有用的工具。例如,很容易编写一个 django 视图,该视图会针对每个页面请求导致数百个 SQL 查询。
  • Opportunity.objects.all() 返回一个惰性查询集。这意味着在这里只调用all() 不会执行数据库查询。在您实际访问数据之前不会执行数据库查询,例如通过迭代它(可能发生在模板代码中)或调用更新、删除等。

标签: python django


【解决方案1】:

如果我正确阅读了文档,这意味着我正在多次访问同一个数据库。

https://pypi.org/project/django-debug-toolbar/

顺便说一句,用这个https://docs.djangoproject.com/en/2.2/ref/models/querysets/#select-related

【讨论】:

  • 我安装了 django-debug-toolbar。谢谢你的提示。但是,调试工具栏的作用是证实我的怀疑。我发现一个特定的耗时查询被调用了 26 次!我正在玩 select_related,但还没有完全弄清楚。文档对我来说不是很清楚,所以如果您有任何其他教程或实现示例可以指点我,不胜感激。
  • 看看this article
猜你喜欢
  • 1970-01-01
  • 2019-09-16
  • 2017-02-07
  • 2013-04-10
  • 2017-09-01
  • 2013-05-02
  • 2014-08-27
  • 1970-01-01
  • 2017-02-13
相关资源
最近更新 更多