#23440: select_related with multiple ForeignKey to same table generates 
sub-optimal
SQL
-------------------------------------+-------------------------------------
     Reporter:  djbug                |                    Owner:  nobody
         Type:                       |                   Status:  new
  Cleanup/optimization               |                  Version:  1.6
    Component:  Uncategorized        |               Resolution:
     Severity:  Normal               |             Triage Stage:
     Keywords:  select_related       |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by djbug):

 * needs_better_patch:   => 0
 * needs_tests:   => 0
 * needs_docs:   => 0


Old description:

> I have this model where Relation has 2 foreign keys, both to Node.
>
> {{{
> class Node(models.Model):
>     name = models.CharField(max_length=25)
>
> class Relation(models.Model):
>     left = models.ForeignKey(Node)
>     right = models.ForeignKey(Node, related_name='right')
>
> }}}
>
> I've shown a sample query along with the SQL that's generated by Django:
>
> {{{
> Relation.objects.select_related().filter(id=1)
>
> SELECT "relation"."id", "relation"."left_id", "relation"."right_id",
> "left"."id", "left"."name", T3."id", T3."name",
> FROM "relation" INNER JOIN "left" ON ( "relation"."left_id" = "left"."id"
> ) INNER JOIN "right" T3 ON ("relation"."right_id" = T3."id" )
> WHERE "relation"."id" = 1
> }}}
>
> There are 2 INNER JOIN happening above. However we can do with just 1
> INNER JOIN, since left & right are pointing to the same table. See below:
>

> {{{
> SELECT "relation"."id", "relation"."left_id", "relation"."right_id",
> "left"."id", "left"."name",
> FROM "relation" INNER JOIN "left" ON ( "relation"."left_id" = "left"."id"
> OR "relation"."right_id" = "left"."id")
> WHERE "relation"."id" = 1
> }}}
>
> P.S. Not sure if this is related :
> https://code.djangoproject.com/ticket/7125

New description:

 I have this model where Relation has 2 foreign keys, both to Node.

 {{{
 class Node(models.Model):
     name = models.CharField(max_length=25)

 class Relation(models.Model):
     left = models.ForeignKey(Node)
     right = models.ForeignKey(Node, related_name='right')

 }}}

 I've shown a sample query along with the SQL that's generated by Django:

 {{{
 Relation.objects.select_related().filter(id=1)
 }}}

 {{{#!sql
 SELECT "relation"."id", "relation"."left_id", "relation"."right_id",
 "left"."id", "left"."name", T3."id", T3."name",
 FROM "relation" INNER JOIN "left" ON ( "relation"."left_id" = "left"."id"
 ) INNER JOIN "right" T3 ON ("relation"."right_id" = T3."id" )
 WHERE "relation"."id" = 1
 }}}

 There are 2 INNER JOIN happening above. However we can do with just 1
 INNER JOIN, since left & right are pointing to the same table. See below:


 {{{
 #!sql
 SELECT "relation"."id", "relation"."left_id", "relation"."right_id",
 "left"."id", "left"."name",
 FROM "relation" INNER JOIN "left" ON ( "relation"."left_id" = "left"."id"
 OR "relation"."right_id" = "left"."id")
 WHERE "relation"."id" = 1
 }}}

 P.S. Not sure if this is related : [7125]

--

--
Ticket URL: <https://code.djangoproject.com/ticket/23440#comment:1>
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 post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/063.f7b90b7093fb2a5f549517b64b67dd76%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to