Opened 2 hours ago

Last modified 54 minutes ago

#35777 new Uncategorized

MySQL: cannot add key limited index on TEXT columns

Reported by: Tobias Krönke Owned by:
Component: Migrations Version: 5.0
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Heyo!

I have a model with a text field url = models.TextField() and I would like to add an index to my MySQL 8.0.36 DB to speed up queries like url__startswith='https://google.com%' -> WHERE url LIKE 'https://google.com%'. I can actually do it by creating an index manually like so:

CREATE INDEX `my_limited_prefix_index` ON `my_model_table` (url(100));

However, I would like to be able to do it with the ORM. Having it only in the migrations as a data migration has many downsides:

  • cannot run tests without running the migrations if i need the index in tests
  • makes squashing migrations more painful

But it seems, this is impossible to achieve with the Meta.indexes:

Index(fields=['url(100)'], name='my_limited_prefix_index')

-> denied by django with (models.E012) 'indexes' refers to the nonexistent field 'url(100)'

Index(expressions.RawSQL('url(100)', ()), name='my_limited_prefix_index')

-> denied by MySQL with syntax error (see https://github.com/sqlalchemy/sqlalchemy/issues/5462, django adds double parantheses which is only valid syntax for expressions, but here I need a column definition)

Index(expressions.RawSQL('LEFT(url,100)', ()), name='my_limited_prefix_index')

-> creates a useless index that cannot be used by MySQL for startswith (aka not sargable anymore).

I guess my favourite solution would be to allow the 2nd way with being able to turn off the surrounding expression parantheses.

Thx!

Change History (3)

comment:1 by Sarah Boyce, 76 minutes ago

Resolution: invalid
Status: newclosed

I feel this functionality exists and the way to go about this might be using Index.expressions and Left

in reply to:  1 comment:2 by Tobias Krönke, 59 minutes ago

Replying to Sarah Boyce:

I feel this functionality exists and the way to go about this might be using Index.expressions and Left

Thx. Unfortunately, your feeling is not accurate. Your suggestion results in the same index created as my 3rd approach in the OP. That index however is useless. It cannot be used by MySQL for speeding up startswith queries.

comment:3 by Tobias Krönke, 54 minutes ago

Resolution: invalid
Status: closednew

This is the kind of index I would like to be able to create: https://dev.mysql.com/doc/refman/8.4/en/create-index.html#create-index-column-prefixes. So called Column Prefix Key Parts.

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