Opened 4 years ago
Last modified 4 years ago
#31940 closed Cleanup/optimization
Order of WHERE clauses do not match the order of the arguments to .filter() — at Version 1
Reported by: | Tommy Li | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.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 (last modified by )
With the following sample model
class MyModel(models.Model): a_field = models.IntegerField() b_field = models.IntegerField()
If I run the following query:
MyModel.objects.filter(b_field = 1, a_field = 2)
the SQL that it generates is
SELECT "mymodel"."a_field", "mymodel"."b_field FROM "mymodel" WHERE ("mymodel"."a_field" = 2 AND "mymodel"."b_field" = 1)
I would expect the order of the clauses in the WHERE statement to match the order of arguments passed to the filter statement. In my case, b_field
has a much higher cardinality than a_field
and I want the query to use an index I have on (b_field, a_field)
After some experimentation, it looks like the WHERE clauses are ordered alphabetically by column name. Is that explicitly intended, or is it just a side effect of some implementation detail?
A workaround is to run
MyModel.objects.filter(b_field = 1).filter(a_field = 2)
But this is pretty inconvenient if you just want to run a .get, you would have to build out a verbose .filter().filter().first() query