Django 6.1 中的 FETCH_PEERS 将 2001 次查询的循环缩减为 2 次”
Django 6.1 引入了 fetch_mode 以解决 N+1 查询问题,而无需显式调用 select_related 或 prefetch_related。fetch_mode 设置,尤其是 FETCH_PEERS,显著减少了外键查询的查询次数和执行时间。测试表明,FETCH_PEERS 将原本 2,001 次循环查询减少至仅 2 次,提升幅度约为 87 倍。该性能增益与使用 select_related 相当,实现了高效的批量获取。然而,FETCH_PEERS 不适用于关系的反向侧,因此对于“多”侧的 N+1 问题仍需使用 prefetch_related。FETCH_RAISE 模式旨在通过阻止字段访问来防止意外懒加载。当将 FETCH_PEERS 与 QuerySet.iterator() 结合使用时存在一个关键陷阱,由于同行跟踪机制的原因,这会退化为 N+1 模式。FETCH_PEERS 还会急切地为查询集批量获取所有相关数据,即使仅访问了子集,在某些场景下可能不如 select_related 高效。在测试规模下,查询集物化及获取相关数据所产生的内存开销较小。并发线程独立运行 FETCH_PEERS 时仍保持 2 次查询计数,表明其在负载下具有鲁棒性。调试查询计数需谨慎关注缓冲区限制,因为超出限制可能导致静默的错误结果。