[英]Django slow query with a nullable Foreignkey
假设我们有这两个模型
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.tracking 上创建的默认索引执行查询时,查询非常慢。 另一方面,当我们摆脱这个索引时,查询速度很快。 我很困惑。
任何人都可以给出解决方案吗? (我想保留索引)
提前致谢
你能试试这个吗?
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())
)
问题是使用 iexact 导致生成的查询在 matching_status 列上执行 upper() function。 这使得数据库不使用索引。
解决方案是更改过滤器以执行精确匹配,以便生成的查询不会操作 matching_status 列。 由于此列正在使用选项,因此最佳做法是使用筛选器中定义的选项。
.filter(tracking__matching_status=Tracking.MANUAL)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.