#31965: MySQL fast-delete optimizations introduced in Django 3.1 don't properly
deal with aggregation and cause performance regression.
-------------------------------------+-------------------------------------
Reporter: Simon | Owner: nobody
Charette |
Type: Bug | Status: new
Component: Database | Version: 3.1
layer (models, ORM) |
Severity: Release | Keywords:
blocker |
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
[https://github.com/django/django/pull/11996#issuecomment-682349899 As
reported on Github] the fast-delete optimization on MySQL to use the
proprietary `DELETE FROM` syntax introduced in #23576 and the follow up
commit to disable it on MariaDB 10.3.1+
5b83bae031a9771d86933bcc808d4bf2e21216a2 are causing performance
regression due it's poor query planing of `DELETE` involving subqueries.
[https://github.com/django/django/pull/11931#issuecomment-547862119 While
investigating the initially reported failure on MariaDB] I noticed that
the MySQL's `SQLDeleteCompiler` implementation was also not properly
dealing while filters against aggregation. It's normally not an issue
because aggregation is done against against many-to-many relationships
that involve reverse `ForeignKey` that usually have an `on_delete` that
require in-memory fetching from `deletion.Collector` (e.g. `CASCADE`,
`SET_NULL`) and thus disable fast-delete. However when only fast-delete
`on_delete` handlers are involved (e.g. `DO_NOTHING` or future database
level `on_delete` support #21961) this can be an issue that results in a
`Invalid use of group function` crash due to an attempt at using aggregate
functions in the `WHERE` clause.
In order to address both issues I suggest we
1. Always use the subquery approach when aggregation is involved
2. Materialize the subquery at the database level when the backend doesn't
have the `update_can_self_select` feature
3. Favor the proprietary `DELETE FROM` syntax otherwise to work around
MySQL poor handling of subqueries and avoid the generation of slow
queries.
--
Ticket URL: <https://code.djangoproject.com/ticket/31965>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/052.175c897621ebc155f89ac316c04923c9%40djangoproject.com.