如何加速这个Django查询?

时间:2016-12-13 10:40:07

标签: python django postgresql

我有这个数据库,里面有近200万条记录,其中很多是重复的(不同的内部id但是'idd'相同)

基本上我需要的是查询数据库以获得只有1个产品(不同的idd)并按'-sold_count'排序的前x个记录

所以这是我正在尝试的查询:

Product.objects.distinct('idd').order_by('idd', '-sold_count')[:2000]

问题1:大约需要30秒,我担心更多数据会花费更长时间。我怎样才能让它更快?

问题2:它也没有按sold_count降序排序,如果有什么似乎正在做相反的事情。我如何通过-sold_count订购?尝试删除“ - ”进行实验但结果似乎相同。

其他信息:

idd是CharField

sold_count是一个IntegerField

希望这很清楚,如果没有,你可以提出任何问题。

型号:

class Product(models.Model):
    price = models.FloatField(default=False, null=True)
    sold_count = models.IntegerField(default=False, null=True)
    revenue = models.FloatField(default=False, null=True)
    idd = models.CharField(max_length=300, default=False, null=True)
    remaining = models.IntegerField(default=False, null=True)
    category = models.CharField(max_length=300, default=False, null=True)
    brand = models.CharField(max_length=300, default=False, null=True)
    seller = models.CharField(max_length=300, default=False, null=True)
    url = models.CharField(max_length=300, default=False, null=True)
    name = models.CharField(max_length=300, default=False, null=True)
    shipment = models.CharField(max_length=300, default=False, null=True)
    view_count = models.IntegerField(default=False, null=True)
    updated = models.DateTimeField(null=True)

发送原始查询:

SELECT DISTINCT ON ("server_gitti"."idd") "server_gitti"."id", "server_gitti"."price", "server_gitti"."sold_count", "server_gitti"."revenue", "server_gitti"."idd", "server_gitti"."remaining", "server_gitti"."category", "server_gitti"."brand", "server_gitti"."seller", "server_gitti"."url", "server_gitti"."name", "server_gitti"."shipment", "server_gitti"."view_count", "server_gitti"."updated" FROM "server_gitti" ORDER BY "server_gitti"."idd" ASC, "server_gitti"."sold_count" ASC LIMIT 2000

1 个答案:

答案 0 :(得分:2)

好吧,如果我知道我要在TextFieldCharField列上搜索,我要做的第一件事就是设置索引:

class Product(models.Model):
    price = models.FloatField(default=False, null=True)
    sold_count = models.IntegerField(default=False, null=True)
    revenue = models.FloatField(default=False, null=True)
    idd = models.CharField(max_length=300, default=False, null=True, db_index=True)
    remaining = models.IntegerField(default=False, null=True)
    category = models.CharField(max_length=300, default=False, null=True)
    brand = models.CharField(max_length=300, default=False, null=True)
    seller = models.CharField(max_length=300, default=False, null=True)
    url = models.CharField(max_length=300, default=False, null=True)
    name = models.CharField(max_length=300, default=False, null=True)
    shipment = models.CharField(max_length=300, default=False, null=True)
    view_count = models.IntegerField(default=False, null=True)
    updated = models.DateTimeField(null=True)

Django rocks uses a 2000 row example, entertainingly

您可能还想查看SQL that Django's running - 如果您在该类(或相关类)上有额外的方法,您可能会触发比您意识到的更多的SQL查询。从表面上看,你的查询非常简单,而且看起来很慢。我在几百万条记录上运行连接,这些记录在我们糟糕的遗留数据库上花费了很长时间。这两种尺寸之间的推文I also had a similar issue on get_or_create queries on a database,通过索引解决。

编辑: 应该添加standard django docs on optimisation,其中还有一些需要注意的事项。

Edit2:看起来select distinct通常相当慢,并且是postgres上的一个已知问题。但是,通过连接查询进行调试是likely to yield some interesting results