【Django】执行查询—检索对象(二)

主键 (pk) 查询快捷方式

pk查询等同于通过模型的 primary key 进行过滤,直接上例子,下面三个语句是等效的。

python 复制代码
>>> Blog.objects.get(id__exact=14)  # Explicit form
>>> Blog.objects.get(id=14)  # __exact is implied
>>> Blog.objects.get(pk=14)  # pk implies id__exact

任何查询条件都可以与 pk 结合使用,pk 查询也可以跨越关联进行。

缓存和 QuerySet

先看一段代码:

python 复制代码
>>> print([e.headline for e in Entry.objects.all()])
>>> print([e.pub_date for e in Entry.objects.all()])

上述代码存在2个问题:

  • 同样的数据库查询会被执行两次,实际加倍了数据库负载;
  • 同时,有可能这两个列表不包含同样的记录,因为在两次请求间,可能有 Entry 被添加或删除了。

因此要学会使用QuerySet缓存。新创建的 QuerySet 缓存是空的。一旦要计算 QuerySet 的值,就会执行数据查询,随后,Django 就会将查询结果保存在 QuerySet 的缓存中,并返回这些显式请求的缓存。因此我们可以优化一下:

python 复制代码
>>> queryset = Entry.objects.all()
>>> print([p.headline for p in queryset])  # Evaluate the query set.
>>> print([p.pub_date for p in queryset])  # Reuse the cache from the evaluation.

QuerySet 没有被缓存的情形

查询结果集并不总是缓存结果。使用数组切片或索引方式得到的 限制查询结果集 不会填充缓存。

例如,反复获取查询集对象中的某个索引会每次查询数据库:

python 复制代码
>>> queryset = Entry.objects.all()
>>> print(queryset[5])  # Queries the database
>>> print(queryset[5])  # Queries the database again

如果整个查询集已经被评估过,那么会检查缓存而不是查询数据库:

python 复制代码
>>> queryset = Entry.objects.all()
>>> [entry for entry in queryset]  # Queries the database
>>> print(queryset[5])  # Uses cache
>>> print(queryset[5])  # Uses cache
相关推荐
RestCloud10 小时前
SQL Server到Hive:批处理ETL性能提升30%的实战经验
数据库·api
RestCloud11 小时前
为什么说零代码 ETL 是未来趋势?
数据库·api
ClouGence13 小时前
CloudCanal + Paimon + SelectDB 从 0 到 1 构建实时湖仓
数据库
c8i16 小时前
django中的FBV 和 CBV
python·django
DemonAvenger20 小时前
NoSQL与MySQL混合架构设计:从入门到实战的最佳实践
数据库·mysql·性能优化
AAA修煤气灶刘哥1 天前
后端人速藏!数据库PD建模避坑指南
数据库·后端·mysql
RestCloud1 天前
揭秘 CDC 技术:让数据库同步快人一步
数据库·api
得物技术2 天前
MySQL单表为何别超2000万行?揭秘B+树与16KB页的生死博弈|得物技术
数据库·后端·mysql
可涵不会debug2 天前
【IoTDB】时序数据库选型指南:工业大数据场景下的技术突围
数据库·时序数据库
ByteBlossom2 天前
MySQL 面试场景题之如何处理 BLOB 和CLOB 数据类型?
数据库·mysql·面试