【发布时间】: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()不会执行数据库查询。在您实际访问数据之前不会执行数据库查询,例如通过迭代它(可能发生在模板代码中)或调用更新、删除等。