zoukankan      html  css  js  c++  java
  • 数据库优化查询

    only与defer

     
    orm内所有的语句操作都是惰性查询:只会在你真正需要数据的时候才会走数据库,如果你单单只写orm语句时不会走数据库的,这样设计的好处在于减轻数据库的压力
    
    res = models.Book.objects.all()
    print(res)
    
    
    res = models.Book.objects.values('title')
    print(res)
    for r in res:
        print(r.title)
    
    
    res = models.Book.objects.only('title')
    print(res)
    for r in res:
         print(r.title)  # 只走一次数据库查询
         print(r.price)  # 当你点击一个不是only括号内指定的字段的时候 不会报错 而是会频繁的走数据库查询
    
    
    res1 = models.Book.objects.defer('title')  # defer与only是相反的
    for r in res1:  # defer会将不是括号内的所有的字段信息 全部查询出来封装对象中
         #一旦你点击了括号内的字段  那么会频繁的走数据库查询
        print(r.price)
     

    总结:用only它会帮你拿到括号内的字段的数据放在一个对象里面,当你拿该字段的数据时就不会再走数据库查询了,但如果你要那其它字段的数据,还是会去数据库查询,而defer与only是完全相反的,defer做的事情则是把你不是括号中字段的数据拿到,封装在对象中,如果你要拿一个不是括号内字段的数据时,它就可以直接而给,而不再去走数据库,如果括号内字段数据的话,它会帮你去数据库查询。

    select_related与prefetch_related

    复制代码
    select_related帮你直接连表操作 查询数据   括号内只能放外键字段
    res = models.Book.objects.all().select_related('publish')
    for r in res:
        print(r.publish.name)
    res = models.Book.objects.all().select_related('publish__xxx__yyy__ttt')
    print(res)
    res = models.Book.objects.all()
    """
    select_related:会将括号内外键字段所关联的那张表  直接全部拿过来(可以一次性拿多张表)跟当前表拼接操作
    从而降低你跨表查询 数据库的压力
    
    注意select_related括号只能放外键字段(一对一和一对多)
    res = models.Book.objects.all().select_related('外键字段1__外键字段2__外键字段3__外键字段4')
    """
    prefetch_related  不主动连表
    res = models.Book.objects.prefetch_related('publish')
    """
    不主动连表操作(但是内部给你的感觉像是连表操作了)  而是将book表中的publish全部拿出来,在取publish表中将id对应的所有的数据取出
    res = models.Book.objects.prefetch_related('publish')
    括号内有几个外键字段 就会走几次数据库查询操作    
    """
    for r in res:
        print(r.publish.name)
    复制代码

    总结:

    1、select_related是主动连表操作,它的作用其实就是把你括号内的外键所关联的表和你当前这张表拼接起来,变成一张表,相当于拿到了所有的数据,你想查谁就能查谁,如果你关联外键的那张表里也有外键,你可以在括号里写当前这张表的外键之后双下划线然后写那张表的名字(例如'外键1__外键2__外键3__外键4'),这样的话就是把这几张表全部拼接在了一起,这个的本质其实就是通过sql的join来优化查询,从而减少sql查询次数。

    2、prefetch_related是不主动连表操作,它的本质其实是分别拿到两张表,然后通过python来处理表的关系,并将对应的数据拿出来封装到一个对象里,也可以让你用点操作拿出来,它看起来也像是连表操作。

    事务

    本质和mysql的事务差不多

    也拥有ACID四大特性:原子性、一致性、隔离性、永久性

    复制代码
    from django.db import transaction
    
    with transaction.atomic():
        """数据库操作
        在该代码块中书写的操作 同属于一个事务
        """
        models.Book.objects.create()
        models.Publish.objects.create()
        # 添加书籍和出版社 就是同一个事务 要么一起成功要么一起失败
    print('出了 代码块 事务就结束')
    复制代码
  • 相关阅读:
    LeetCode Single Number
    Leetcode Populating Next Right Pointers in Each Node
    LeetCode Permutations
    Leetcode Sum Root to Leaf Numbers
    LeetCode Candy
    LeetCode Sort List
    LeetCode Remove Duplicates from Sorted List II
    LeetCode Remove Duplicates from Sorted List
    spring MVC HandlerInterceptorAdapter
    yum
  • 原文地址:https://www.cnblogs.com/AbrahamChen/p/11567328.html
Copyright © 2011-2022 走看看