需要帮助优化此Django聚合查询吗

需要帮助优化此Django聚合查询吗,django,optimization,Django,Optimization,我有下面的型号 class Plugin(models.Model): name = models.CharField(max_length=50) # more fields 它代表了一个可以从我的网站下载的插件。要跟踪下载,我必须 class Download(models.Model): plugin = models.ForiegnKey(Plugin) timestamp = models.DateTimeField(auto_now=True) 因

我有下面的型号

class Plugin(models.Model):
    name = models.CharField(max_length=50)
    # more fields
它代表了一个可以从我的网站下载的插件。要跟踪下载,我必须

class Download(models.Model):
    plugin = models.ForiegnKey(Plugin)
    timestamp = models.DateTimeField(auto_now=True)
因此,为了构建一个显示按下载排序的插件的视图,我有以下查询:

# pbd is plugins by download - commented here to prevent scrolling
pbd = Plugin.objects.annotate(dl_total=Count('download')).order_by('-dl_total')
这很有效,但速度很慢。只有1000个插件,平均响应时间为3.6-3.9秒(带有本地PostgreSQL db的devserver),而类似的视图和更简单的查询(按插件发布日期排序)大约需要160毫秒

我正在寻找关于如何优化此查询的建议。我真的希望查询返回
插件
对象(而不是使用
),因为我为其他视图(按评级的插件、按发布日期的插件等)共享相同的模板,因此模板需要
Plugin
对象,而且我不确定在不引用Plugin对象的情况下如何获得像绝对url这样的东西

或者,我的整个方法注定要失败吗?有没有更好的方法跟踪下载?我最终想为用户提供一些他们上传的插件的下载统计数据,比如每天/每周/每月的下载量。我需要在某个时候计算并缓存下载吗


编辑:在我的测试数据集中,每个插件大约有10-20个下载实例-在生产中,我希望对于许多插件来说,这个数字会高得多。

注释显然很慢,因为它们需要更新数据库中的每个记录

一种直接的方法是对db字段进行非规范化。在插件模型上使用
download\u count
字段,该字段在新的下载保存时递增。在插件上使用聚合查询排序


如果您认为将有太多的下载来更新插件的另一条记录,您可以通过cron更新插件上的
download\u count
字段。不过,在您的查询中没有任何明显的东西会导致这种缓慢。我在过去使用更大的数据集进行过非常类似的查询,它们的执行时间为毫秒


目前我唯一的建议是安装Django调试工具栏,并在其SQL选项卡中找到有问题的查询,然后进行解释,让数据库准确地告诉您它在执行时正在做什么。例如,如果它正在执行子查询,请检查它们是否正在使用索引——如果没有,则可能需要在db中手动定义一个索引。如果您愿意,请将解释结果张贴在此处,如果可能,我将进一步提供帮助。

这种方法的缺点是我会丢失时间戳。这将允许我只跟踪总下载量。Chris,我说的是,覆盖
下载
模型的保存,您可以在其中更新下载计数。你们两个都可以!有趣的是,我后来在sqlite DB上测试了相同的代码,速度要快得多。我丢失了原来的PostgreSQL数据库,所以我想我永远也找不到问题出在哪里了。有时,当我对模型进行更改时,我只是手动添加或删除DB列,通常不添加索引。。。