假设我有一个这样的模型:
class Post(models.Model):
name = models.CharField(max_length=25, unique=True)
class Picture(models.Model):
post = models.ForeignKey(to=Post, ondelete=models.CASCADE)
image = models.ImageField()
现在假设我执行如下查询:
p = Post.objects.get(name=foo)
images = p.picture_set.all()
现在,第一个查询显然会搜索所有帖子以获取具有名称的帖子foo
.
但我想知道第二个。它是否搜索所有Picture
数据库中的表查找所有包含的图片post=p
或者当我得到信息时可用p
在第一个查询中?
因为如果是前者,那么我担心可扩展性问题。
但我想知道第二个。它是否搜索数据库中的所有图片表以查找所有具有 post=p 的图片,或者当我在第一个查询中获得 p 时该信息是否可用?
简短回答: 默认情况下ForeignKey
添加索引,使得检索速度相当快(值的数量呈对数,反向记录的数量呈线性)。
这取决于数据库是否构建索引ForeignKey
。默认情况下,Djangowill构造一个索引。这意味着它不仅存储表的行,而且还存储一个允许快速查找具有特定值的所有行的数据结构。
索引的实现可以依赖于数据库。在 MySQL 中,它默认使用BTREE
,这意味着查找一个值大约需要O(log n)获取集合,并且O(k) with k使用该外键检索所有项目的数量。但是还存在其他索引结构,例如某种哈希表,甚至允许(稍微)更快地查找,尽管哈希表在检索所有元素时效率不高ForeignKey
小于给定数字。
您还可以在其他列上添加索引,例如:
class Post(models.Model):
name = models.CharField(max_length=25, db_index=True, unique=True)
所以现在检索所有Post
具有给定名称的对象也会运行得更快。
使用索引当然不是“免费的”:这意味着每次插入或删除记录时,索引也需要更改(通常这也需要O(log n))。如果通过更改外键的值来更新记录,则该索引也需要更改。因此,索引提供了显着的加速,但应该只在经常执行查找的列上放置索引,否则“维护”索引的成本可能大于加速查找过程的收益。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)