prefetch_one_level is slow
|Reported by:||simonpercivall||Owned by:||nobody|
|Component:||Database layer (models, ORM)||Version:||1.4|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
prefetch_one_level in django.db.models.query.py does a lot of I think unnecessary extra work.
For every obj in instances a QuerySet is created for the related many to many by doing getattr(obj, attname).all(). This QuerySet however is never really used, instead its _prefetched_objects_cache is filled with the prefetched items.
qs = getattr(obj, attname).all() qs._result_cache = vals obj._prefetched_objects_cache[cache_name] = qs
If instead you'd simply create a QuerySet you save having to call clone for every obj, which is very expensive.
qs = QuerySet(getattr(obj, attname).model) qs._result_cache = vals obj._prefetched_objects_cache[cache_name] = qs
For a function like prefetch_related whose main purpose is to speed up a certain case of use, speed seems like a good quality. Maybe I've misunderstood an edge case here, but if not, this is an easy optimization that gives quite the speedup.
All modeltests on 1.4 pass with this change, by the way.
Change History (7)
comment:1 Changed 3 years ago by simonpercivall
- Cc percivall@… added
- Needs documentation unset
- Needs tests unset
- Patch needs improvement unset
comment:5 Changed 3 years ago by aaugustin
- Triage Stage changed from Unreviewed to Design decision needed
comment:6 Changed 2 years ago by aaugustin
- Triage Stage changed from Design decision needed to Accepted