Django学习之ORM性能相关

 

orm 性能相关

  values

    第一步:创建表

class Student(models.Model):
    
    name = models.CharField(max_length=32)
    classes = models.ForeignKey('Class',)

class Class(models.Model):
    name = models.CharField(max_length=16)

     views.py文件中

from django.shortcuts import render
from app01 import models
# Create your views here.

def index(request):
    all_students = models.Student.objects.all().values('classes__id','classes__name')
    # all_students = models.Student.objects.all()
    for i in all_students:
        # print(i.name,i.classes_id) # 1.通过django-debug-toolbar可以看到
        # 查询本表子段的时候用到了一次sql查询
        # print(i.name,i.classes.id,i.classes.name) # 2.但是如果进行关联表数据的查询
        print(i['classes__id'],i['classes__name']) # 4.首先通过values进行了连表操作,效率就高一些了
        

    return render(request,'index.html',{'all_students':all_students})

 

  select_related

    但是如果查询结果,就想是对象,就想通过对象.属性的操作,怎么办呢?用到了select_related

from django.shortcuts import render
from app01 import models
# Create your views here.

def index(request):
    all_students = models.Student.objects.all().select_related('classes')
    # 使用了select_related之后,里面的参数写的是关系字段的名称,那么就会先进行
    # 连表操作,所以sql也是执行了一次,效率高一些,但是他用在外键或者一对一的关系上
    for i in all_students:
        # print(i.name,i.classes_id)
        print(i.name,i.classes.id,i.classes.name)

 

   

  prefetch_related 

    子查询效果。

from django.shortcuts import render
from app01 import models
# Create your views here.

def index(request):
    all_students = models.Student.objects.all().prefetch_related('classes')
    # prefetch_related,里面的参数写的是关系字段的名称,那么会执行两次sql,子查询的效果,但是支持外键或一对一或者一对多的查询了
    for i in all_students:
        # print(i.name,i.classes_id)
        print(i.name,i.classes.id,i.classes.name)


    return render(request,'index.html',{'all_students':all_students})

 

 

  only和defer

    当我们进行orm查询的时候,你通过翻译出来的sql语句可以看到,每次查询都是查询了每个字段的数据,所以我们通过only和defer,可以指定查询哪些字段数据

from django.shortcuts import render
from app01 import models
# Create your views here.

def index(request):
    all_students = models.Student.objects.all().only('name')#只要这个字段数据
    all_students = models.Student.objects.all().defer('name')#排除,除了这个字段其他字段数据都要
    for i in all_students:
        print(i.name)


    return render(request,'index.html',{'all_students':all_students})

 

 

   总结:

1.能用values的尽量不查询对象,然后对象.属性的操作
2.select_related 主动连表,针对一对一或者外键
3.perfetch_related 子查询 ,针对一对一或者外键或者多对多
4.only只查询指定字段数据  defer排除某些字段

 

posted @ 2019-11-06 13:13  cls超  阅读(563)  评论(0编辑  收藏  举报