Django - набор запросов и общие вопросы SQL - PullRequest
0 голосов
/ 10 июня 2011

Во-первых, , учитывая модель Foo и ее m2m, указывающую на Bar, как работает следующий запрос (когда на самом деле ничего не является NULL как таковым (объединение и первая часть опущены):

>> print Foo.objects.get(bar__isnull=True).query
...WHERE "barapp_bar"."id" IS NULL

Нулевой материал отбрасывает меня в отношении фильтрации по связанным м2м.

Во-вторых, , есть ли способ ускорить выполнение подобного запроса при работе с большим количеством строк:

Foo.objects.get(bar__in=[bar1, bar2, bar3, bar4])

1 Ответ

0 голосов
/ 10 июня 2011

Пропущенные объединения важны.Если вы посмотрите на полный запрос, то увидите, что Django выполняет два левых внешних соединения из таблицы foo к соединительной таблице foo_bar и к таблице bar.

Рассмотрим два foos и два bars.Пусть foo_1 относится к bar_1 и bar_2, а foo_2 не относится к каким-либо bars.

В приведенном ниже запросе с двумя левыми внешними объединениями, по крайней мере, каждый foo включаетодин раз, и NULL появится в столбце столбца для foo_2, который не связан ни с одним bars.

SELECT foo.id as foo_id, bar.id as bar_id 
FROM foo LEFT OUTER JOIN foo_bar 
  ON foo_id = foo_bar.foo_id
LEFT OUTER JOIN bar
  ON foo_bar.bar_id = bar.id;
+--------+--------+
| foo_id | bar_id | 
+--------+--------+
| 1      | 1      |
| 1      | 2      |
| 2      | NULL   |
+--------+--------+

Запрос для Foo.objects.get(bar__isnull=True) похож на этот, но он не выбираетчто-нибудь из таблицы столбцов, и это фильтрует на bar.id, равно NULL, потому что нам нужны только foos, которые не связаны с bars.

SELECT foo.id as foo_id 
FROM foo LEFT OUTER JOIN foo_bar 
  ON foo_id = foo_bar.foo_id
LEFT OUTER JOIN bar
  ON foo_bar.bar_id = bar.id
where bar_id is NULL;
+--------+
| foo_id | 
+--------+
| 2      |
+--------+
...