代码之家  ›  专栏  ›  技术社区  ›  Arbazz Hussain

Django在M2M上执行查询的有效方法

  •  1
  • Arbazz Hussain  · 技术社区  · 6 年前
    class A(models.Model)
      results = models.TextField()
    
    class B(models.Model)
      name = models.CharField(max_length=20)
      res = models.ManyToManyField(A)
    
    • 假设我们有两个以上的模型。 A 模型有数百万个对象。

    我想知道什么是最有效/最快的方法 results objects 特别的 B 反对。

    • 假设我们必须检索对象号的所有结果 5 属于 乙
    Option 1 :  A.objects.filter(b__id=5)
    
       (OR)
    
    Option 2 : B.objects.get(id=5).res.all()
    
    • 选项1:我的问题是按id筛选 一个 模型对象需要很多时间?因为有数百万 一个 模型对象。
    • 选项2:问题:是否 res 打开字段 乙 模型存储 id 价值 一个 模型对象?

    我之所以选择 2 因为它存储了 一个 建模对象&首先直接获取这些对象值,然后进行第二次查询以获取结果。而在第一个选项中,按id或任何其他字段过滤将占用大量时间

    1 回复  |  直到 6 年前
        1
  •  2
  •   willeM_ Van Onsem    6 年前

    这个 第一个表达式 会导致 一 数据库查询。事实上,它会质疑:

    SELECT a.*
    FROM a
    INNER JOIN a_b ON a_b.a_id = a.id
    WHERE a_b.b_id = 5

    这个 第二个表达式 会导致 二 询问。实际上,第一个Django将查询以获取 B 对象的查询如下:

    SELECT b.*
    FROM b
    WHERE b.id = 5

    然后它将执行完全相同的查询来检索相关的 A 物体。

    但是找回 一个 对象在这里是不必要的(除非你当然需要它在其他地方)。因此,您将生成一个无用的数据库查询。

    我的问题是按模型对象上的id进行筛选会花费很多时间?因为有数百万个模型对象。

    数据库通常在外键字段上存储索引。这意味着它将有效过滤。的总数 一个 对象通常不相关(因为它使用数据结构来加速搜索,就像 B-tree [wiki] ). wiki页面有一个部分 named An index speeds the search 这就解释了它的工作原理。

    推荐文章