在预取相关减慢查询之前添加 'only'

Adding 'only' before prefetch related slows down query

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

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 之间有什么区别,为什么会造成性能瓶颈?

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"]]