Py学习  »  Django

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

Arbazz Hussain • 6 年前 • 2482 次点击  
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或任何其他字段过滤将占用大量时间

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/52369
文章 [ 1 ]  |  最新文章 6 年前
Willem Van Onsem
Reply   •   1 楼
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 这就解释了它的工作原理。