1、避免N+1查询问题

  • N+1 查询只是在查询列表,每次访问对象的关联字段(外键或者多对多字段)汇单独查询,导致大量不必要的查询

  • 解决方案:使用 select_related 和 prefetch_related 来优化关联查询

    • select_related: 用于一对一和外键关系的查询,会通过SQl的JOIN来一次性获取相关对象,减少查询次数
  # 例子:查询所有作者及其书籍信息
authors = Author.objects.select_related('book').all()
  • prefetch_related: 用于多对多和反向外键关系,Django会在后台执行额外的查询结果缓存到Python中,避免多次查询数据库。
  # 例子:查询所有作者及其书籍信息
authors = Author.objects.prefetch_related('books').all()

2、只查询必要的字段

  • 在不需要查询整个对象的情况下,使用 values() 或 values_list() 来只获取特定字段。
  • 使用 only() 和 defer() 可以减少查询时加载的字段量,only() 只加载指定的字段,defer() 延迟加载指定的字段。

# 只获取特定字段
queryset = Author.objects.only('name', 'age')

# 延迟加载某个字段
queryset = Author.objects.defer('bio')

3、批量操作

# 批量插入数据
authors = [Author(name="John"), Author(name="Jane")]
Author.objects.bulk_create(authors)

4、使用数据库索引字段进行查询

-对经常用于查询、过滤和排序的字段添加索引,能显著提高查询效率。Django 可以通过模型中的 index_together 或 unique_together 来创建复合索引。

class Author(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()

    class Meta:
        indexes = [
            models.Index(fields=['name', 'age']),
        ]

5、缓存查询结果,避免多次查询数据库

6、使用原生SQL,绕过ORM的瓶颈

7、限制查询的结果集

使用 filter() 或 exclude() 来缩小查询范围,只返回符合条件的数据。

通过 limit 或 slice 方法限制返回的结果集(如 [:10])。

12. 使用 Q 对象进行复杂查询

使用 Q 对象构建复杂的 AND、OR 查询条件,在数据库层面进行高效查询。

from django.db.models import Q

# 查询符合某些复杂条件的对象
authors = Author.objects.filter(
    Q(name__startswith="J") | Q(age__gte=30)
)

__END__