django中查询的select_related方法和prefetch_related方法

33 篇文章 0 订阅
11 篇文章 0 订阅
select_related - 数据库上的join

Django考虑到了标准查询这种低效的查询方式,因此在设计ORM的时候设计了提升性能的方式。select_related就是其中之一。select_related将会根据外键关系,在执行查询语句的时候一次性获得相关对象的信息,这种操作带来的结果是更加复杂的查询语句和避免对于即将使用的外键对象的额外数据库查询。Django的文档详细的描述了相关内容,在此只进行简要介绍。标准的查询代码如下:

b = B.objects.get(id=2)
a = b.a

换用select_related之后,代码如下:

b = B.objects.select_related('a').get(id=2)  

'a’是B模型存在关联的A模型,指定a可以只查询A和B的数据,如果没有参数,则查询出所有相关联的model信息。
我们可以看到,select_related实际上是在数据库层面进行了一次inner join操作,因此一次性获取了所有需要的信息,也就是说使用select_related()方法一次性的把B关联的对象都查询出来放入对象中,再次查询时就不需要再连接数据库,节省了后面查询数据库的次数和时间。

需要注意的是,我们可以使用任意外键关系(ForeignKeyField)或一对一关系(OneToOneField)作为参数传给select_related,同时也可以使用反向的一对一关系,此时应使用related_name作为参数。某些情况下,你可能想获取所有的相关对象,或者你并不知道关联关系,此时可以使用不加参数的.select_related(),该方式下将会根据关联关系(级联的)获取所有关联的对象, 即假设有外键关系为A。

prefetch_related - Python上的join

与select_related类似,prefetch_related也可以大幅提高查询效率,但是prefetch_related的方式跟select_related大不一样。select_reateld是通过创建一条包含SQL join操作的SELECT语句来一次性获得所有相关对象的信息。因此,select_related需要从同一个数据库中获得相关对象。但是,为了避免由于join操作带来的较大的查询集结果,select_related被限制在了单值关系——外键关系或一对一关系

另一方面,prefetch_related为每一个关系使用了单独的查询,并在Python层面进行’join’操作,因此该操作允许多对多关系以及反向关系,而这是select_related无法做到的。我们这次使用prefetch_related执行查询,代码如下:

b = B.objects.prefetch_related('a').get(id=2)

可以看到,Django首先进行了id=5的第一次查询获取对象b,然后根据外键关系进行了第二次查询获取b.a。为了增强理解,我们引入第三个模型C,这次我们从A模型上查询id__lte=5的A对象及其相关对象,代码如下:

class C(models.Model):
	b = models.Foreignkey(B, related_name='cs')
qs = A.objects.prefetch_related('bs', 'bs__cs').filter(id__lte=5)

Django首先查询了id小于等于5的所有A对象,然后根据反向关联关系,查询所有外键到这些A对象的B对象,然后查询所有外键到这些B对象的C对象。

select_related与prefetch_related性能对比:
在查询集中的对象字段较多较复杂,且查询集较大的时候,或需要使用反向外键关系或多对多关系作为参数优化查询的时候,应该选用prefetch_related,在查询集中对象字段简单的,查询集不大的时候,应选用select_related。

下面链接介绍的更详细:

https://blog.csdn.net/cugbabybear/article/details/38342793

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: `select_related` 是 Django ORM 的一个方法,用于查询关联模型的数据。它可以避免进行多次数据库查询,从而提高查询效率。 例如,如果你有一个模型 `Author` 和一个模型 `Book`,并且一个作者可以对应多本书,那么你可以使用以下代码来获取一个作者对应的所有书: ``` author = Author.objects.get(pk=1) books = Book.objects.filter(author=author) ``` 这样会导致两次数据库查询,第一次查询获取作者的数据,第二次查询获取书的数据。 如果使用 `select_related`,就可以一次性获取作者和对应的所有书: ``` author = Author.objects.select_related().get(pk=1) books = author.book_set.all() ``` 这样只需要进行一次数据库查询查询速度会更快。 ### 回答2: select_relatedDjango ORM的一个功能,用于优化查询性能。它通过使用JOIN操作一次性将多个相关模型的数据取出,避免了多次查询数据库的问题。 在默认情况下,当我们访问一个模型对象的外键或者一对一关联字段时,Django会自动发出相应的数据库查询。这意味着在处理大量对象时,会导致大量查询操作,严重影响性能。 而select_related的作用就是通过指定需要一起查询的相关模型,一次性将这些相关模型的数据取出,避免多次查询。这样,我们就可以在一次数据库访问获取所有相关模型的数据。使用select_related可以大幅减少数据库的访问次数,提高查询性能。 使用select_related非常简单,只需要在查询时使用select_related()方法,并指定需要查询的相关模型即可。如下所示: Model.objects.select_related('related_model') 其,Model是主要要查询的模型类,related_model是Model的一个关联字段。使用select_related后,查询结果将包含主要模型和相关模型的所有数据。 需要注意的是,使用select_related查询可能会导致较大的数据集被加载到内存,如果查询结果集很大,可能会导致性能问题。因此,在使用select_related时,应该根据实际情况谨慎使用,避免查询结果集过大。 综上所述,select_relatedDjango ORM的一个优化查询性能的功能,通过一次性将多个相关模型的数据取出,避免了多次查询数据库的问题。使用方法简单,在查询时使用select_related()方法,并指定需要查询的相关模型即可。但需要注意查询结果集的大小,避免性能问题的发生。 ### 回答3: select_relatedDjango ORM的一个方法,用于在查询数据库时进行关联查询,减少查询次数,提高查询效率。它可以在一次查询同时查询多个相关联的表,而不需要多次查询select_related方法的使用非常简单,只需要在查询时使用它即可。例如,假设有一个模型A与模型B关联,我们可以通过以下方式使用select_related: A.objects.select_related('B').filter(条件) 这里的条件可以是任意的查询条件,比如过滤某些数据。select_related('B')表示在查询A模型时同时查询与之关联的B模型。 使用select_related方法的好处是,它会执行一次SQL查询,将A模型和B模型的数据一起返回。这样可以避免在使用A模型数据时,每次都去查询关联的B模型数据,从而减少了数据库查询的次数,提高了查询效率。 需要注意的是,select_related只能进行一层的关联查询,不能进行多层的关联。如果要进行多层关联查询,可以使用prefetch_related方法。 另外,使用select_related方法还需谨慎,因为它会将所有关联的数据一起查询出来,如果关联的数据量很大,会占用大量内存。所以,在使用时要根据实际情况考虑是否使用select_related,并合理设计数据库的关联关系。 总之,select_relatedDjango ORM非常实用的方法,可以在一次查询同时查询多个相关联的表,减少数据库查询次数,提高查询效率。但需要注意使用时的内存占用问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值