#33759: Using subquery to filter a model delete creates sub-optimal SQL
-------------------------------------+-------------------------------------
     Reporter:  bertonha             |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  4.0
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:
                                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Description changed by bertonha:

Old description:

> Taking in consideration the app of tutorial for demonstrate the issue.
> using postgresql as db.
>
> Executing this following code:
>
> {{{
> subquery = Comment.objects.filter(created_at__lt=datetime(2022, 6,
> 1))[:1000]
> Comment.objects.filter(id__in=subquery).delete()
> }}}
>
> Generates the following SQL:
>
> {{{
> DELETE FROM "comment" WHERE "comment"."id" IN (SELECT V0."id" FROM
> "comment" V0 WHERE V0."id" IN (SELECT U0."id" FROM "comment" U0 WHERE
> U0."created_at" < \'2022-06-01T00:00:00+00:00\'::timestamptz LIMIT 1000))
> }}}
>
> The inner **select V0** is completely unnecessary
>
> If a simple select with the same subquery is executed. It generates
> expected SQL query.
>
> {{{
> subquery = Comment.objects.filter(created_at__lt=datetime(2022, 6,
> 1))[:1000]
> comments = list( Comment.objects..filter(id__in=subquery) )
> }}}
>
> {{{
> SELECT * FROM "comment" WHERE "comment"."id" IN (SELECT U0."id" FROM
> "comment" U0 WHERE U0."created_at" <
> '2022-06-01T00:00:00+00:00'::timestamptz LIMIT 1000),
> }}}

New description:

 Taking in consideration the app of tutorial for demonstrate the issue.
 using postgresql as db.

 Executing this following code:

 {{{
 subquery = Comment.objects.filter(created_at__lt=datetime(2022, 6,
 1))[:1000]
 Comment.objects.filter(id__in=subquery).delete()
 }}}

 Generates the following SQL:

 {{{
 DELETE FROM "comment" WHERE "comment"."id" IN (SELECT V0."id" FROM
 "comment" V0 WHERE V0."id" IN (SELECT U0."id" FROM "comment" U0 WHERE
 U0."created_at" < '2022-06-01T00:00:00+00:00'::timestamptz LIMIT 1000))
 }}}

 The inner **select V0** is completely unnecessary

 If a simple select with the same subquery is executed. It generates
 expected SQL query.

 {{{
 subquery = Comment.objects.filter(created_at__lt=datetime(2022, 6,
 1))[:1000]
 comments = list( Comment.objects..filter(id__in=subquery) )
 }}}

 {{{
 SELECT * FROM "comment" WHERE "comment"."id" IN (SELECT U0."id" FROM
 "comment" U0 WHERE U0."created_at" <
 '2022-06-01T00:00:00+00:00'::timestamptz LIMIT 1000),
 }}}

--

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33759#comment:2>
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 django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070181201ab895-736400ca-20b3-4d5a-8aab-d70dcfd9ad56-000000%40eu-central-1.amazonses.com.

Reply via email to