ORM性能相关
model:
先给一个简单的表结构
from django.db import models class User(models.Model): username=models.CharField(max_length=32) pwd=models.CharField(max_length=64) pd=models.ForeignKey('Depart',on_delete=models.CASCADE) class Depart(models.Model): title=models.CharField(max_length=32)
only
需求:在user表中获取所有的username和id
a.需求: 只取n列 queryset=[{},{}] model.User.objects.all().values('id','username') queryset=[(),()] model.User.objects.all().values_list('id','username') queryset=[obj,obj] obj只有id和name result=model.User.objects.all().only('id','username') for item in result: print(item.id,item.username,item.pwd) age没有,去数据库再查一次...for循环几次就再查几次性能很低
需要注意的是:
- 如果取了only以外的字段,虽然可以取的到,但是他内部会重新查一次表
- 如果循环取only以外的字段就会重复多次查表操作
defer
defer跟only想对应,是排除哪些字段
result=model.User.objects.all().defer('id','username')排除哪列
select_related
###连表操作,相当于主动做join
需求:获取所有人的用户和所在部门
用户表和部门表示多对一的关系
result=model.User.objects.all() for obj in result: print(obj.username,obj.dp.title)
上述的ORM语句性能非常差
因为for循环一次都需要跨一次表
跨表查询的性能极低!!!!!!!!!!
优化:
result=model.User.objects.all().select_related('dp') for item in result: print(item.name,item.dp(Fk).title)
相当于一开始就连表了,再取的时候不需要再重新跨表操作
sql:
select * from user left join depart on user.dp.id=depart.id
需要说明的是:
selected_related只支持FK,和OnetoOne
如果连表多性能也越来越差.
prefetch_related
###
多次单表操作,先查询想要的数据,
然后构建条件,如:id=[1,2,3],再查询其他表的时候,根据id做条件
###
result=User.object.all().prefetch_related('dp') for item in result: print(item.name,item.dp.title)
sql
#select * from user # 通过python代码获取:所有dp_id=[1,2] # select * from depart where id in dp_id
说明:
- 支持M2M FK One
- 2次单表查询
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人