Django-数据库访问优化

时间:2023-03-09 09:35:15
Django-数据库访问优化

数据库访问优化

使用标准数据库优化技巧

  1. 索引。我们可以使用Field.db_index或者Meta.index_together在Django中添加索引,优先向经常使用filter(),exclude(),order_b()等查询的字段添加索引,帮助我们更快的查找。
  2. 合理使用字段类型

了解QuerySets

  理解QuerySets 是通过简单的代码获取较好性能至关重要的一步:

要避免性能问题,理解以下几点非常重要:

    • QuerySets 是惰性的。
    • 什么时候他们被评估。
    • 数据保存在内存中。

和整个QuerySet的缓存相同,ORM对象的属性的结果中也存在缓存。 通常来说,不可调用的属性会被缓存。 例如下面的example Weblog models

 entry = Entry.objects.get(id=)
entry.blog # Blog object is retrieved at this point
entry.blog # cached version, no DB access

但是通常来讲,可调用的属性每一次都会访问数据库。

entry = Entry.objects.get(id=)
entry.authors.all() # query performed
entry.authors.all() # query performed again

要小心当你阅读模板代码的时候 —— 模板系统不允许使用圆括号,但是会自动调用callable对象,会隐藏上述区别。

要小心使用你自定义的属性 —— 实现所需的缓存取决于你,例如使用cached_property装饰符。

使用with模板标签

要利用QuerySet的缓存行为,你或许需要使用with模板标签。

使用iterator()

当你有很多对象时,QuerySet的缓存行为会占用大量的内存。 这种情况下,采用iterator()解决。

在数据库中而不是python中做数据工作

用唯一的被索引的列来检索独立对象

一次性检索你需要的任何东西

不要检索你不需要的东西

批量插入

创建对象的时候,尽可能使用bulk_create()来减少SQL查询的数量。此方法以高效的方式(通常只有1个查询,无论有多少对象)将提供的对象列表插入到数据库中:,例如:

Entry.objects.bulk_create([
Entry(headline='This is a test'),
Entry(headline='This is only a test'),
])

优于:

Entry.objects.create(headline='This is a test')
Entry.objects.create(headline='This is only a test')

注意 :

  • 将不会调用模型的save()方法,并且不会发送pre_savepost_save信号。
  • 它不适用于多表继承场景中的子模型。
  • 如果模型的主键是AutoField,则不会像save()那样检索并设置主键属性,除非数据库后端支持(当前是PostgreSQL)。
  • 它不适用于多对多关系。

这也可以用在ManyToManyField中,所以:

my_band.members.add(me, my_friend)

优于

my_band.members.add(me)
my_band.members.add(my_friend)