在相关预取之前添加“仅”会减慢查询速度

时间:2019-09-15 14:58:07

标签: django django-orm

在伪代码中,我有一个这样的数据库模型:

Model T
    name
    tags = models.ManyToManyField(Tag, related_name="Ts")
    symbol = models.ForeignKey(Symbol)

Model Symbol
    name
    category = models.ForeignKey(Category)

Model Tag
    name

这是我用来导出它的代码:

query = T.objects.annotate(category_id=F('symbol__category_id')).prefetch_related('tags')

for t in query:
    _dict = model_to_dict(t)
    _dict["category_id"] = t.category_id

    _tags = []
    for tag in _dict["tags"]
        _tags.append(tag.id)
    _dict["tags"] = _tags

在这段代码中,_dict给了我想要的结果。

但是,T还有许多我不需要的其他字段,因此我将query更改为:

T.objects.only("name", "symbol", "tags").annotate(category=F('symbol__category_id')).prefetch_related('tags')

由于某种原因,这会降低执行速度。

原始查询需要6秒,而最后一个查询需要8秒。为什么?

如何正确地预取所有内容,从而不必遍历标签并将其ID附加到字典中?如何同时使用.only()来做到这一点?

编辑:

由于某些原因,使用.defer()而不是仅使用它,并指出我不需要的字段,可以在不影响性能的情况下起作用。

deferonly有什么区别,为什么会造成性能瓶颈?

1 个答案:

答案 0 :(得分:1)

使用fields = ("name", ...)

from django.db.models import Prefetch
prefetch = Prefetch('tags', queryset=Tag.objects.only('id'))
query = T.objects.prefetch_related(prefetch).annotate(category_id=F('symbol__category_id')).only(*fields)

for t in query:
    _dict = model_to_dict(t, fields=[*fields, tags])
    _dict["category_id"] = t.category_id
    _dict["tags"] = [tag.id for tag in _dict["tags"]]