I too would be interested to know if there is a solution. A LEFT OUTER JOIN
can really hurt performance when an INNER JOIN are more appropriate,.


On Mon, Jul 15, 2013 at 8:41 AM, Carsten Fuchs <[email protected]>wrote:

> Hi all,
>
> we have two queries/QuerySets Q_a and Q_b, each of which use INNER joins
> in the generated SQL when evaluated individually.
>
> When I use a Q object to "OR" these two QuerySets, the INNER joins turn
> into LEFT OUTER joins -- which in turn cause a huge performance drop
> (several hundred times slower than with INNER joins).
>
> Why is this, and can I do anything against it at the Django ORM level?
>
>
> Details:
>
> My environment:
> Django 1.5.1 on Ubuntu 10.04 (Python 2.6.5) with Oracle database 10g
>
>
> FirstDay = date(2013, 5, 1)
> LastDay = date(2013, 5, 31)
> SomeDep = ...   # the department with ID == 1
>
>
> Q_a = Staff.objects. \
>       filter(bereiche=SomeDep).**distinct()
>
> Q_b = Staff.objects. \
>       filter(erfasst__datum__gte=**FirstDay,
>              erfasst__datum__lte=LastDay,
>              erfasst__bereich=SomeDep).**distinct()
>
> Q_a_or_b = Staff.objects. \
>       filter(Q(bereiche=SomeDep) |
>              Q(erfasst__datum__gte=**FirstDay,
>                erfasst__datum__lte=LastDay,
>                erfasst__bereich=SomeDep)).**distinct()
>
>
> In the following output, to improve readability I used the "*" to manually
> shorten the list of selected fields:
>
>
> print Q_a.query
>
> SELECT DISTINCT "STAFF".* FROM "STAFF"
> INNER JOIN "STAFF_BEREICHE" ON ("STAFF"."ID" = "STAFF_BEREICHE"."STAFF_ID")
> WHERE "STAFF_BEREICHE"."BEREICH_ID" = 1
>
>
> print Q_b.query
>
> SELECT DISTINCT "STAFF".* FROM "STAFF"
> INNER JOIN "ERFASST" ON ("STAFF"."KEY" = "ERFASST"."KEY")
> WHERE ("ERFASST"."DATUM" <= 2013-05-31  AND "ERFASST"."DATUM" >=
> 2013-05-01  AND "ERFASST"."BEREICH_ID" = 1 )
>
>
> print Q_a_or_b.query
>
> SELECT DISTINCT "STAFF".* FROM "STAFF"
> LEFT OUTER JOIN "STAFF_BEREICHE" ON ("STAFF"."ID" =
> "STAFF_BEREICHE"."STAFF_ID")
> LEFT OUTER JOIN "ERFASST" ON ("STAFF"."KEY" = "ERFASST"."KEY")
> WHERE ("STAFF_BEREICHE"."BEREICH_ID" = 1  OR ("ERFASST"."DATUM" <=
> 2013-05-31  AND "ERFASST"."DATUM" >= 2013-05-01  AND "ERFASST"."BEREICH_ID"
> = 1 ))
>
>
> In the last SQL statement, when I replace "LEFT OUTER JOIN" with "INNER
> JOIN" and manually run it, the result seems to be the same, but the query
> completes one hundred to several hundred times faster.
>
> So, from the above observations, I was wondering if the use of "LEFT OUTER
> JOIN" is what is supposed to happen for Q_a_or_b in the first place? Is it
> the expected behavior?
> And if so, can it be changed via the Django ORM?
>
> Many thanks for your help!
>
> Best regards,
> Carsten
>
>
>
> --
> Dipl.-Inf. Carsten Fuchs
>
> Carsten Fuchs Software
> Industriegebiet 3, c/o Rofu, 55768 Hoppstädten-Weiersbach, Germany
> Internet: http://www.cafu.de | E-Mail: [email protected]
>
> Cafu - the open-source game and graphics engine for multiplayer 3D action
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to 
> django-users+unsubscribe@**googlegroups.com<django-users%[email protected]>
> .
> To post to this group, send email to [email protected].
> Visit this group at 
> http://groups.google.com/**group/django-users<http://groups.google.com/group/django-users>
> .
> For more options, visit 
> https://groups.google.com/**groups/opt_out<https://groups.google.com/groups/opt_out>
> .
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-users.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to