当前位置: 首页 > news >正文

django之select_related 与 prefetch_related用法

在 Django 中,select_relatedprefetch_related 是用于优化查询的两个重要方法。它们通过减少数据库查询次数来提高性能,但它们的工作方式有所不同。

select_related

select_related 使用 SQL 的 JOIN 操作来获取相关对象。它适用于一对一和多对一的关系(如 ForeignKey 和 OneToOneField)。它会在单个查询中获取相关对象的数据,从而减少数据库查询次数。

示例

假设我们有以下模型:

from django.db import modelsclass Author(models.Model):name = models.CharField(max_length=100)email = models.EmailField()def __str__(self):return self.nameclass Book(models.Model):title = models.CharField(max_length=200)publication_date = models.DateField()author = models.ForeignKey(Author, related_name='books', on_delete=models.CASCADE)def __str__(self):return self.title

可以使用 select_related 来优化查询:

# 获取所有书籍及其对应的作者
books = Book.objects.select_related('author').all()for book in books:print(f"{book.title} by {book.author.name}")

在这个示例中,select_related('author') 会在单个查询中获取所有书籍及其对应的作者,从而避免了每次访问 book.author 时的额外查询。

prefetch_related

prefetch_related 使用单独的查询来获取相关对象,然后在 Python 中进行关联。它适用于一对多和多对多的关系(如 ForeignKey、OneToOneField 和 ManyToManyField)。它会在单独的查询中获取相关对象的数据,然后在内存中进行关联。

示例

假设我们有以下模型:

from django.db import modelsclass Author(models.Model):name = models.CharField(max_length=100)email = models.EmailField()def __str__(self):return self.nameclass Book(models.Model):title = models.CharField(max_length=200)publication_date = models.DateField()author = models.ForeignKey(Author, related_name='books', on_delete=models.CASCADE)def __str__(self):return self.title

可以使用 prefetch_related 来优化查询:

# 获取所有作者及其对应的书籍
authors = Author.objects.prefetch_related('books').all()for author in authors:print(f"Books by {author.name}:")for book in author.books.all():print(f" - {book.title}")

在这个示例中,prefetch_related('books') 会在单独的查询中获取所有作者及其对应的书籍,然后在内存中进行关联,从而避免了每次访问 author.books.all() 时的额外查询。

选择 select_related 还是 prefetch_related

  • select_related适用于一对一和多对一的关系。它使用 SQL JOIN 操作,在单个查询中获取相关对象的数据。
  • prefetch_related适用于一对多和多对多的关系。它使用单独的查询来获取相关对象的数据,然后在内存中进行关联。

组合使用

在某些情况下,可能需要同时使用 select_relatedprefetch_related 来优化查询。

示例

假设我们有以下模型:

from django.db import modelsclass Publisher(models.Model):name = models.CharField(max_length=100)def __str__(self):return self.nameclass Author(models.Model):name = models.CharField(max_length=100)email = models.EmailField()publisher = models.ForeignKey(Publisher, related_name='authors', on_delete=models.CASCADE)def __str__(self):return self.nameclass Book(models.Model):title = models.CharField(max_length=200)publication_date = models.DateField()author = models.ForeignKey(Author, related_name='books', on_delete=models.CASCADE)def __str__(self):return self.title

可以同时使用 select_relatedprefetch_related 来优化查询:

# 获取所有书籍及其对应的作者和出版社
books = Book.objects.select_related('author__publisher').prefetch_related('author__books').all()for book in books:print(f"{book.title} by {book.author.name} (Publisher: {book.author.publisher.name})")print("Other books by this author:")for other_book in book.author.books.all():if other_book != book:print(f" - {other_book.title}")

在这个示例中,select_related('author__publisher') 会在单个查询中获取书籍、作者及其对应的出版社,而 prefetch_related('author__books') 会在单独的查询中获取作者及其对应的书籍,然后在内存中进行关联。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • windows C++- C++/WinRT和COM组件(下)
  • Python编写Word文档
  • css-定位
  • 【Linux】——进程概念(万字解读)
  • 【嵌入式linux开发】智能家居入门6:最新ONENET,物联网开放平台(QT、微信小程序、MQTT协议、ONENET云平台、旭日x3派)
  • Linux环境下运行介绍
  • 51单片机学习
  • 第八季完美童模全球总冠军·韩嘉潞 破浪扬帆写就传奇
  • INSTALLMENT MORTGAGE
  • Mac升级系统文件都丢了怎么办?Mac更新后资料找不到了怎么恢复
  • 【ARM 芯片 安全与攻击 6 -- ARM 中的 PAC 是什么?】
  • 2024年电赛H题全开源
  • 深度学习(YOLO、DETR) 十折交叉验证
  • 一个简单的Rtmp推流客户端(QT录音,OpenCV摄像,FFmpeg编码推流)
  • 模糊Smith智能控制方法的研究 及其单片机实现
  • AHK 中 = 和 == 等比较运算符的用法
  • flask接收请求并推入栈
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • JavaScript学习总结——原型
  • Java的Interrupt与线程中断
  • Java精华积累:初学者都应该搞懂的问题
  • Nacos系列:Nacos的Java SDK使用
  • STAR法则
  • ViewService——一种保证客户端与服务端同步的方法
  • windows-nginx-https-本地配置
  • Xmanager 远程桌面 CentOS 7
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 区块链技术特点之去中心化特性
  • 如何合理的规划jvm性能调优
  • 深入浏览器事件循环的本质
  • 提醒我喝水chrome插件开发指南
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • 用Python写一份独特的元宵节祝福
  • 正则学习笔记
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​插件化DPI在商用WIFI中的价值
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • (06)Hive——正则表达式
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (4)事件处理——(7)简单事件(Simple events)
  • (floyd+补集) poj 3275
  • (备忘)Java Map 遍历
  • (二) 初入MySQL 【数据库管理】
  • (二)hibernate配置管理
  • (剑指Offer)面试题34:丑数
  • (十三)Flink SQL
  • (四)汇编语言——简单程序
  • (转)Windows2003安全设置/维护
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • .NET C# 配置 Options