【问题标题】:Django - queryset and general SQL questionsDjango - 查询集和一般 SQL 问题
【发布时间】: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])

【问题讨论】:

    标签: python django query-optimization django-queryset


    【解决方案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 命令创建了表,那么您的表应该有合适的索引,以便查询高效。
    猜你喜欢
    • 2017-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-03
    • 1970-01-01
    • 2013-12-10
    • 2022-06-16
    • 2011-11-05
    相关资源
    最近更新 更多