【问题标题】:How to optimize use of querysets with lists如何使用列表优化查询集的使用
【发布时间】:2011-07-15 08:38:32
【问题描述】:

我有一个包含几百万个对象的模型。每个对象代表公司拨打/接听的电话。

为简化起见,假设这个模型 Call 具有以下字段:
调用日期、上下文、频道。

我的目标是了解当月一天中每个小时的平均拨打和接听电话数(按小时加载)。问题是:我需要分别为 port1port2 找到这个。

截至目前,我的代码运行良好,只是需要大约 1 分钟才能给我 4 个月的结果,而且我似乎效率极低。

我做了一些简单的分析,发现 extend 占用了大约 99% 的处理时间:

queryset = Call.objects.filter(calldate__gte='SOME_DATE')
port1, port2 = [],[]
port1.extend(queryset.filter(context__icontains="e1-1"))
port2.extend(queryset.filter(context__icontains="e1-2"))
channels_in_port1 = ["Port/%d-2" % x for x in range(1,32)]
channels_in_port2 = ["Port/%d-2" % x for x in range(32,63)]

for i in channels_in_port1:
    port1.extend(queryset.filter(channel__icontains=i))
for i in channels_in_port2:
    port2.extend(queryset.filter(channel__icontains=i))

port1 和 port2 现在组合了大约 150k 个对象。

当我收到所有对 port1port2 的调用后,我就可以开始了。其余代码基本上是 port1port2 的一些 for 循环,它们根据小时/天/月总结并取平均调用次数。琐碎的东西。

我试图通过使用 itertools.chain 并链接查询集来避免使用任何“扩展”。但是,这使得处理时间转移到我执行琐碎的 for 循环以按小时计算负载的部分。

还有其他选择吗?过滤查询集的更好方法?
非常感谢!!

【问题讨论】:

  • 你能贴出你的模型的代码吗?

标签: django django-queryset


【解决方案1】:

我认为您的问题在于第二组扩展,即 for 循环中的扩展,而不是第一组。 (无论如何,第一个是完全没有必要的:与其预先定义一个空列表并对其进行扩展,不如直接使用port1 = list(queryset.filter(context__icontains="e1-1"))。)

无论如何,总结一下我认为你正在尝试做的事情:你想在两个块中获取某个日期的所有 Call 对象,具体取决于channel 的值:一个包含从 0 到31,一个值在 32 到 62 之间。

您似乎只需两个查询就可以做到这一点,根本不需要任何扩展:

port1 = queryset.filter(channel__range=["Port/1-2", "Port/31-2"])
port2 = queryset.filter(channel__range=["Port/1-32", "Port/31-62"])

这不是你想要的吗?

根据评论进行编辑,但这只是您可以扩展或连接的两个查询。您发布的代码的问题是您正在为每个端口执行 31 查询和扩展操作,这肯定会很昂贵。如果你只做一个,加上一个extend/concat,那会便宜得多。

【讨论】:

  • 是的,我知道第一部分是不必要的,但是将查询集转换为列表所需的处理时间与扩展它的处理时间几乎相同。无论哪种情况,这都无关紧要。 :) 第二部分,像你提到的那样进行两个查询是行不通的,原因如下:port1 应该是一个列表,其中包含具有定义的通道范围的 Call 对象和字段“context”为“e1-1”的 Call 对象.这两个不是一起发现的。我不能只是链接过滤器。我可能需要研究像 Aaron 提到的聚合函数,或者可能只是将其分解为更多列表......
【解决方案2】:

你考虑过使用 django 的聚合函数吗? http://docs.djangoproject.com/en/dev/topics/db/aggregation/

【讨论】:

    猜你喜欢
    • 2017-08-09
    • 2018-11-08
    • 2019-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-20
    • 2018-03-08
    • 1970-01-01
    相关资源
    最近更新 更多