I have some references (strings) that I want to use to filter a query with a case-insensitive exact match. To do so, I used iexact Django field lookup.
Model.objects.filter(column1__iexact=reference)
Since I have a very large number of rows on that table, I wanted to create an index to speed up the query. Django uses the UPPER function to perform the iexact lookup.
So I created the following migration (DB is Postgresql):
class Migration(migrations.Migration):
dependencies = [
('app', 'previous_migr'),
]
operations = [
migrations.RunSQL(
sql=r'CREATE INDEX "index_name_idx" ON "table" (UPPER("column1") );',
reverse_sql=r'DROP INDEX "index_name_idx";'
),
]
Unfotunately, this index does not seem to be used while querying.
Why do I think this ? Here are the request times with :
- iexact ~= 17s
- exact < 1s
Here is the generated (truncated) SQL query :
SELECT "table"."id" FROM "table"
WHERE (
"table"."is_removed" = false
AND (UPPER("table"."column1"::text) = UPPER('blablabla')
OR UPPER("ordering_order"."column2"::text) = UPPER('blablabla')))
ORDER BY "table"."id" ASC
)
Is there something wrong with my migration ? Any other option to do this query with good performance ?