Opened 5 years ago

Last modified 4 months ago

#16043 assigned Cleanup/optimization

Specialization cache should be filled/shared with parent object cache (multitable inheritance)

Reported by: Piotr Czachur Owned by: Paulo
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Here is some multi-table inheritance example:

class Owner(models.Model):
    nick = models.CharField(max_length=100)

class Car(models.Model):
    owner = models.ForeignKey(Owner)
    some_id = models.CharField(max_length=100)
    
class MiniMorris(Car):
    mini_type = models.CharField(max_length=1)

- model: auto.Owner
  pk: 1
  fields:
    nick: Homer

- model: auto.Car
  pk: 1
  fields:
    owner: 1
    some_id: 'minii A'
    
- model: auto.MiniMorris
  pk: 1
  fields:
    mini_type: 'e'
>>> c = Car.objects.select_related('owner').get(pk=1)
>>> # SELECT "auto_car"."id", "auto_car"."owner_id", "auto_car"."some_id", "auto_owner"."id", "auto_owner"."nick" FROM "auto_car" INNER JOIN "auto_owner" ON ("auto_car"."owner_id" = "auto_owner"."id") WHERE "auto_car"."id" = 1

>>> c.owner
<Owner: Owner object>
>>>  # No SQL, cache hit.

>>> m = c.minimorris
>>> # SELECT "auto_car"."id", "auto_car"."owner_id", "auto_car"."some_id", "auto_minimorris"."car_ptr_id", "auto_minimorris"."mini_type" FROM "auto_minimorris" INNER JOIN "auto_car" ON ("auto_minimorris"."car_ptr_id" = "auto_car"."id") WHERE "auto_minimorris"."car_ptr_id" = 1 
>>> # SQL is fine, we need to obtain this specialization

>>> m.owner
<Owner: Owner object>
>>>  # SELECT "auto_owner"."id", "auto_owner"."nick" FROM "auto_owner" WHERE "auto_owner"."id" = 1 
>>>  # Redundant SQL. This could be obtained from cache.

SQL issued by "m.owner" is redundant as owner is already cached in parent object.

Attachments (1)

16043-testcase.patch (2.1 KB) - added by Aymeric Augustin 5 years ago.

Download all attachments as: .zip

Change History (10)

comment:1 Changed 5 years ago by Aymeric Augustin

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset
Triage Stage: UnreviewedAccepted

This looks a lot like #15250, but it's not exactly the same bug. At least, the patch currently available on #15250 does not fix this issue.

I'm attaching a test case in the form of a patch.

Changed 5 years ago by Aymeric Augustin

Attachment: 16043-testcase.patch added

comment:2 Changed 5 years ago by Aymeric Augustin

UI/UX: unset

Change UI/UX from NULL to False.

comment:3 Changed 3 years ago by Aymeric Augustin

The issue still exists. However, it can be reproduced without select_related. The problem is really in model inheritance. So the test case I wrote two years ago is inappropriate.

comment:4 Changed 12 months ago by Tim Graham

#25173 seems to be a duplicate and also has a test.

comment:5 Changed 4 months ago by Paulo

Owner: changed from nobody to Paulo
Status: newassigned

comment:6 Changed 4 months ago by Paulo

Has patch: set

comment:7 Changed 4 months ago by Philip James

I believe the PR czpython made for this ticket is https://github.com/django/django/pull/6721.

comment:8 Changed 4 months ago by Paulo

Has patch: unset

comment:9 Changed 4 months ago by Paulo

Removed the has patch set flag as PR 6721 is only the base for this.
The fix will be in a separate PR.

Note: See TracTickets for help on using tickets.
Back to Top