Django——模型的一些优化

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wzyaiwl/article/details/90176923

select_related()

该方法用于关联的多表查询,在数据库有外键的时候,使用select_related()可以很好的减少数据库请求的次数,从而提高性能。该方法类似于sql的INNER JOIN。

对于一对一字段(OneToOneField)和外键字段(ForeignKey),可以使用select_related()来对QuerySet进行优化.在对QuerySet使用select_related()函数后,Django会获取相应外键对应的对象,从而在之后需要的时候不必再查询数据库了。

  • select_related() 接受可变长参数

每个参数是需要获取的外键(父表的内容)的字段名,以及外键的外键的字段名、外键的外键的外键…。若要选择外键的外键需要使用两个下划线“__”来连接。

  • select_related(depth = num) 接受depth参数

depth参数可以确定select_related的深度。Django会递归遍历指定深度内的所有的OneToOneField和ForeignKey.。select_related() 也可以不加参数,这样表示要求Django尽可能深的select_related。

prefetch_related()

对于多对多字段(ManyToManyField)和一对多(ForeignKey)字段,可以使用prefetch_related()来进行优化.

prefetch_related()和select_related()的设计目的很相似,都是为了减少SQL查询的数量,但是实现的方式不一样。后者 是通过JOIN语句,在SQL查询内解决问题。但是对于多对多关系,使用SQL语句解决就显得有些不太明智,因为JOIN得到的表将会很长,会导致SQL 语句运行时间的增加和内存占用的增加。若有n个对象,每个对象的多对多字段对应Mi条,就会生成Σ(n)Mi 行的结果表。

select_related()的效率要高于prefetch_related()。因此,最好在能用select_related()的地方尽量使用它,也就是说,对于ForeignKey字段,避免使用prefetch_related()。

only(*field)

我们在表查询时,有时并不是需要将所有的字段都查询出来,这时我们可以使用only方法,将需要的字段写上,减少查询所耗的资源。

defer(*field)

该方法与only方法刚好相反,将不需要的字段当作参数写进。

save(update_filed = [*field])

在涉及到对表数据的修改时,我们也许会用到save方法。但有时我们仅仅是修改了个别字段的值,这时直接使用save,也会造成不必要的资源浪费。

扫描二维码关注公众号,回复: 6228181 查看本文章

我们可以使用默认参数update_field ,以列表的形式将要修改的字段名写入即可。

values(*field)、value_list(*field)

对于输出的结果,可以指定需要输出的字段,values和value_list是一个不错选择。values获得是一个列表嵌套字典,value_list得到一个列表嵌套元组。

建议

  1. 在任何位置使用QuerySet.exists()或者QuerySet.count()都会导致额外的查询;
  2. 不要做无所谓的排序,排序并非没有代价,每个排序的字段都是数据库必须执行的操作;
  3. 如果要插入多条数据,则使用bulk_create来批量插入,减少sql查询的数量;
  4. 对于缓存的QuerySet对象使用with标签,可以让数据被缓存起来使用;
  5. 在通过all语句查询时,不要做跨表查询,只查询当前表中有的数据,否则查询语句的性能会下降很多;
  6. 如果想判断是否存在外键,只需要判断外键的id即可;
  7. 避免过多的使用count和exists函数;
  8. 如果要一次查询出集合的数量,使用count函数,而不是len函数,但是如果后面还需要到集合,那就用len,因为count还需要进行一次数据库的操作;

猜你喜欢

转载自blog.csdn.net/wzyaiwl/article/details/90176923