only与defer的数据查询优化
select_related与prefetch_related数据查询优化
惰性查询 如果你仅仅只是书写了orm语句 在后面根本没有用到该语句所查询出来的参数 那么orm会自动识别 直接不执行 示例: res = models.Book.objects.all() print(res) # 要用数据了才会走数据库
# 实现获取到的是一个书籍对象 然后点title就能够拿到书名 并且没有其他字段 res = models.Book.objects.only('title') # res = models.Book.objects.all() for i in res: print(i.title) # 点击only括号内的字段 不会走数据库 # print(i.price) # 点击only括号内没有的字段 会重新走数据库查询 # 而all不需要走数据库
# 对象除了没有title属性之外 其他的都有,除了title走数据库,其他都不需要走数据库 res = models.Book.objects.defer('title') for i in res: print(i.title)
defer与only刚好相反 defer括号内的字段不在查询出来的对象里面 查询该字段需要重新走数据 而如果查询的是非括号内的时候 则不需要走数据库
# 拿到每一本书对应的出版社 res = models.Book.objects.select_related('publish') # INNER JOIN for i in res: print(i.publish.name)
1.select_related内部直接先将book与publish连接起来 2.然后一次性将大表里面的所有数据全部封装给查询出来的对象 3.这个时候对象无论是点击book表数据还是publish的数据都无需再走数据库查询了 select_related括号内只能放外键字段 一对一 一对一 多对多也不支持
res = models.Book.objects.prefetch_related('publish') # 子查询 for i in res: print(i.publish.name)
prefetch_related该方法内部其实就是子查询 将子查询查询出来的所有结果也给你封装到对象中 给你的感觉好像也是一次性搞定的
select_related: 相当于是INNER JOIN 将两张表拼接起来! prefetch_related: 相当于是 子查询 分布查询!