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次单表查询
原文地址:https://www.cnblogs.com/chenxuming/p/9380847.html