You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中bulk_update与update的性能优势及查询次数疑问

Django批量更新性能对比与查询次数疑问

问题背景

我有这段代码:

Subscription.objects.filter(id__in=[subscription.id for subscription in subscriptions]).update(renewal_notification_sent=True)

想知道换成下面的写法有没有性能优势:

updatable_subscriptions = []
subs = Subscription.objects.filter(id__in=[subscription.id for subscription in subscriptions])
for sub in subs:
    sub.renewal_notification_sent = True

updatable_subscriptions.append(
    subs
)

# then
Subscription.objects.bulk_update(updatable_subscriptions, ["renewal_notification_sent"])

另外,调用filter后再执行update会产生两次数据库查询吗?

解答

1. 性能对比:哪种写法更好?

你的第二种写法没有性能优势,反而更差,原因很直接:

  • 第一种写法是直接在数据库层面执行单条UPDATE语句,所有更新操作一次完成,只发起一次数据库请求,效率最高。
  • 第二种写法先执行了一次SELECT查询,把所有符合条件的Subscription对象拉到内存里,接着循环修改内存中的对象属性,最后调用bulk_update。这里不仅多了一次查询开销,数据量大的时候还会占用更多内存;而且bulk_update默认会分批次处理(每批次最多1000条),生成多条UPDATE语句,整体开销远大于第一种写法。

另外你的第二种写法还有个小bug:updatable_subscriptions.append(subs)会把整个QuerySet作为单个元素塞进列表,而bulk_update需要的是对象列表,正确的写法应该直接传subs或者list(subs),但就算修正了这个问题,性能还是不如第一种写法。

2. filter后执行update的查询次数

不会产生两次查询。Django的QuerySet是惰性求值的——调用filter只是构建了查询条件,并不会立刻执行SQL。只有当你调用update()时,才会把filter条件和update操作合并成一条完整的UPDATE语句发送给数据库,全程只执行一次数据库查询。

比如你写的代码最终会生成类似这样的SQL:

UPDATE subscription SET renewal_notification_sent = True WHERE id IN (...);

内容的提问来源于stack exchange,提问作者E_K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 15:07:07