Django - 查询集和一般 SQL 问题

Posted

技术标签:

【中文标题】Django - 查询集和一般 SQL 问题【英文标题】:Django - queryset and general SQL questions 【发布时间】:2011-06-09 22:08:27 【问题描述】:

首先,给定一个模型 Foo 并且它的 m2m 指向 Bar,下面的查询是如何工作的(当什么都不是 NULL 本身时(加入和省略第一部分) :

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

关于按相关 m2m 过滤,null 的东西让我很反感。

其次,在处理大量行时,有没有办法让类似的查询更快:

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

【问题讨论】:

【参考方案1】:

省略的连接很重要。如果您查看完整的查询,您会看到 Django 从foo 表到连接表foo_barbar 表执行了两个Left Outer Joins。

考虑两个foos 和两个bars。让foo_1bar_1bar_2 相关,而foo_2 不与任何bars 相关。

下面的查询带有两个左外连接,每个foo 至少包含一次,NULL 将出现在与任何bars 无关的foo_2 的条形列中。

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      |
+--------+

【讨论】:

谢谢!第二个问题是什么,关于实现相同结果的优化查询?有可能吗? 我对你的第二个问题没有任何建议。如果您使用 Django 的 syncdb 命令创建了表,那么您的表应该有合适的索引,以便查询高效。

以上是关于Django - 查询集和一般 SQL 问题的主要内容,如果未能解决你的问题,请参考以下文章

BigQuery:使用标准 SQL 查询多个数据集和表

django基础知识之模型查询:

Django数据操作

准备好的语句,结果集和查询问题[关闭]

Django中数组的并集和交集

Django - - 基础 - - Django ORM常用查询语法及进阶