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__