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次单表查询