使用可为null的Foreignkey的Django慢速查询



假设我们有这两个型号的

class Offer(models.Model):
fetch_datetime = models.DateTimeField(db_index=True)
tracking = models.ForeignKey(Tracking, models.SET_NULL, blank=True, null=True)

class Tracking(models.Model):
MANUAL = "Manual"
AUTO = "Auto"
UNMATCHED = "Unmatched"
MATCHING_TYPES = [(MANUAL, "Matched by a human"), (AUTO, "Matched by a computer"), (UNMATCHED, "Not matched")]
matching_status = models.CharField(max_length=10, choices=MATCHING_TYPES, default=UNMATCHED)

我们想像这样查询

Offer.objects.filter(fetch_datetime__range=(now_minus_14days, now))
.select_related('tracking')
.filter(tracking__matching_status__iexact="manual")
.annotate(
fetch_day=Cast("fetch_datetime", DateField())
)

当使用django在字段Offer上创建的默认索引执行查询时,跟踪查询的速度非常慢。另一方面,当我们去掉这个索引时,查询会很快。我很困惑。

有人能给出解决方案吗?(我想保留索引(

提前感谢

使用iexact的问题导致生成的查询在matching_status列上执行upper((函数。这使得数据库不使用索引。

解决方案是更改过滤器以进行精确匹配,这样生成的查询就不会操作matching_status列。由于此列使用的是选项,因此最好在筛选器中使用已定义的选项。

.filter(tracking__matching_status=Tracking.MANUAL)

你能试试这个吗?

Offer.objects.filter(
fetch_datetime__range=(now_minus_14days, now), 
tracking__matching_status__iexact="manual").select_related('tracking')
.annotate(
fetch_day=Cast("fetch_datetime", DateField())
)

最新更新