Добрый вечер,
Я следую django документации по созданию запросов, и появился этот пример:
Blog.objects.filter(entry__headline__contains='Lennon').filter(entry__pub_date__year=2008)
Я надеялся, что соответствующий запрос SQL при этом задействовано только одно внутреннее соединение и предложение OR, поскольку соответствующие результаты являются записями, которые удовлетворяют одному или обоим условиям.
Тем не менее, проверка запроса набора запросов вернула следующее:
>>> qs = Blog.objects.filter(entry__headline__contains='Lennon').filter(entry__pub_date__year=2008)
>>> print(qs.query)
SELECT "blog_blog"."id", "blog_blog"."name", "blog_blog"."tagline"
FROM "blog_blog"
INNER JOIN "blog_entry" ON ("blog_blog"."id" = "blog_entry"."blog_id")
INNER JOIN "blog_entry" T3 ON ("blog_blog"."id" = T3."blog_id")
WHERE ("blog_entry"."headline" LIKE %Lennon% ESCAPE '\'
AND T3."pub_date" BETWEEN 2008-01-01 AND 2008-12-31)
Вы можете видеть, что он выполняет ДВА внутренних соединения.
Разве результат не будет таким же, как:
SELECT "blog_blog"."id", "blog_blog"."name", "blog_blog"."tagline"
FROM "blog_blog"
INNER JOIN "blog_entry" ON ("blog_blog"."id" = "blog_entry"."blog_id")
WHERE ("blog_entry"."headline" LIKE %Lennon% ESCAPE '\' OR "blog_entry"."pub_date" BETWEEN 2008-01-01 AND 2008-12-31)
?
И этот более поздний запрос AFAIK быстрее.
(добавлены разрывы строк для удобства чтения)