繁体   English   中英

Django 使用可空外键的慢查询

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM