Hello hello,
I have a model similar to this:
class event(models.Model):
label = models.CharField(...)
type = models.PositiveSmallIntegerField('Type', ...)
model1 = models.ForeignKey('models.Model1', null=True, blank=True, on_delete=models.CASCADE)
model2 = models.ForeignKey('models.Model2', null=True, blank=True, on_delete=models.CASCADE)
Now when migrating, django automatically creates:
- database constraints
- two indices, using
model1_id
andmodel2_id
as the columns.
And that’s fine.
However, let’s imagine I want to index things slightly more cleverly, for example:
class event(models.Model):
label = models.CharField(...)
type = models.PositiveSmallIntegerField('Type', ...)
model1 = models.ForeignKey('models.Model1', null=True, blank=True, on_delete=models.CASCADE)
model2 = models.ForeignKey('models.Model2', null=True, blank=True, on_delete=models.CASCADE)
class Meta:
indexes = [
models.Index(
name='my_composite_index_name',
fields=['model1', 'type']
),
models.Index(
name='my_composite_index_name_2',
fields=['model2', 'type']
),
]
or even:
class Meta:
indexes = [
models.Index(
name='my_composite_index_name',
fields=['model1', 'model2', 'type']
),
]
That looks like it is going to work, until we run an explain against the SQL (mysql 8.xx, django 3.2.14) generated for a query similar to the following:
qs = Model1.objects.annotate(
event_count=SubqueryCount(
Event.objects.only('pk').filter(
model1__pk=OuterRef('pk'),
type=1,
)
)
).filter(
event_count__gt=0,
)
The query plan seems to indicate that the non composite index is always picked. The one created by django.
So then let’s choose and turn off indexing for that foreign key:
model1 = models.ForeignKey('models.Model1', null=True, blank=True, on_delete=models.CASCADE, db_index=False)
- run
makemigrations
- run
migrate
…
and message is: No migration to apply.
What am I doing wrong?