#35442: N+1 queries from RelatedManager + only("pk") -------------------------------------+------------------------------------- Reporter: REGNIER | Owner: nobody Guillaume | Type: | Status: new Uncategorized | Component: Database | Version: 4.2 layer (models, ORM) | Severity: Normal | Keywords: Triage Stage: | Has patch: 0 Unreviewed | Needs documentation: 0 | Needs tests: 0 Patch needs improvement: 0 | Easy pickings: 0 UI/UX: 0 | -------------------------------------+------------------------------------- When iterating over a queryset constructed from a RelatedManager and a {{{.only(...)}}} call that does not include the related field, a query occurs when instances are produced from the queryset.
=== Steps to Reproduce: {{{#!python class Company(models.Model): pass class Employee(models.Model): company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name="employees") }}} {{{#!python company = Company.objects.create() Employee.objects.bulk_create(Employee(company=company) for _ in range(10)) for employee in company.employees.only("pk"): # Some code that only access pk _ = employee.pk }}} === Expected Behavior: One query like {{{#!sql SELECT "employee"."id" FROM "employee" WHERE "employee"."company_id" = {COMPANY_ID} }}} === Actual Behavior: 10 additional queries like: {{{#!sql SELECT "employee"."id", "employee"."company_id" FROM "employee" WHERE "employee"."id" = {EMPLOYEE_ID} }}} === Analysis: My understanding is that there is an optimization that fills the parent model on related instances without needing additional SQL join/query. However, when only a subset of fields is selected (in this case, only the primary key), the parent ID might not be loaded from the database, resulting in additional queries to perform said optimization. === Workaround: {{{#!python company = Company.objects.create() Employee.objects.bulk_create(Employee(company=company) for _ in range(10)) for employee in Employee.objects.filter(company=company).only("pk"): # Some code that only access pk _ = employee.pk }}} -- Ticket URL: <https://code.djangoproject.com/ticket/35442> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/0107018f6344fff5-d478091f-a4b5-47b4-b56b-6bcb542c4ceb-000000%40eu-central-1.amazonses.com.