在预取相关减慢查询之前添加 '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()
而不是仅使用,并指出我不想要的字段,在没有任何性能影响的情况下工作。
defer
和 only
之间有什么区别,为什么会造成性能瓶颈?
和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"]]
在伪代码中,我有一个这样的数据库模型:
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()
而不是仅使用,并指出我不想要的字段,在没有任何性能影响的情况下工作。
defer
和 only
之间有什么区别,为什么会造成性能瓶颈?
和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"]]