Django中prefetch_related后调用exists()是否触发新查询?
首先直接给结论:当你通过prefetch_related预取了things1这类多对多关联数据后,调用r[0].things1.exists()会生成新的数据库查询,不会使用已经预取到内存中的数据。
为什么会这样呢?这是因为Django的PrefetchRelatedObjectsManager(也就是预取后关联对象的管理器)并没有重写exists()方法——这个方法本质上还是会构造一个SELECT EXISTS(...)的SQL语句发送给数据库,完全不会去检查已经预取到本地的缓存数据。
那如果想用预取的信息做存在性检查,确实用bool(r[0].things1.all())会更高效。因为all()在预取完成后,会直接返回已经加载到内存中的关联对象集合,转成布尔值只需要在内存中判断集合是否为空,完全不会触发额外的数据库查询,性能上肯定更优。
举个简单的对比:
- 调用
exists():会发起一条SELECT EXISTS(SELECT 1 FROM ... WHERE ...)的SQL查询 - 调用
bool(all()):直接读取预取的缓存,内存内完成判断,无数据库交互
内容的提问来源于stack exchange,提问作者dabadaba
相关产品推荐
相关产品推荐

