我已经读过distinct()API调用有时会遇到一些性能问题。我想尝试通过orm重写一个查询,避免使用distinct(至少描述差异)。
我的理解是values()执行Group By引擎盖。但是,当我测试这两种方法时,对象的数量会有所不同,具体取决于我是使用distinct()还是使用values()/ annotate()。
zip_codes = Location.objects.values('zip_code').annotate(zip_count=Count('zip_code')).exclude(zip_code=None).count()
VS
zip_codes = Location.objects.values_list('zip_code', flat=True).exclude(zip_code=None).distinct()
对这里有什么问题的想法?
谢谢!
答案 0 :(得分:2)
我只是快速检查了我对具有类似查询的数据库的查询。计数相同,所以我不确定您的数据会导致问题。
尽管如此,我还是对这个前提持怀疑态度。 DISTINCT确实是一个cpu密集型查询。但是,COUNT(*)也是如此,您的第二个查询将首先使用group by运行计数聚合,然后对结果运行COUNT。我会把钱放在单个DISTINCT调用上更快(我还要检查你用来查看的数据库后端)。所有这些与django的ORM几乎没什么关系,而且与你的数据库后端有很多关系。还要想一想。与基于注释的查询相比,基于不同的查询比其完成的内容更清楚一个数量级。你是否有证据支持DISTINCT在你的情况下会变慢,或者更好的是它现在正在形成一个瓶颈?如果不是,你已经进入了过早优化的范围,并且应该重新考虑你的道路。
优化仅在重要时才有意义。重要的是,这很重要,但在你知道这很重要之前,不要浪费很多时间去做。即使你知道这很重要,你也需要知道它的重要性。如果没有性能数据,您将不知道要优化什么,并且您可能会优化错误的东西。
结果将是模糊的,难以编写,难以调试,并且难以维护无法解决问题的代码。因此,它具有以下双重缺点:(a)增加软件开发和软件维护成本,以及(b)根本没有性能影响。
换句话说,清楚地编写软件,然后在发现问题时将其跟踪到源并进行修复。你之前做的任何事情都会适得其反。花点时间担心哪些索引对您的数据库有影响,以及在哪里使用select_related。这些比你在这里担心的效率高10000%(除非你一直在计算邮政编码,在这种情况下让我向你介绍缓存)