You need to enable JavaScript to run this app. Python中如何加快exchangelib QuerySet对象转JSON数组的速度
优惠活动
大模型
产品
解决方案
定价
更多

Python中如何加快exchangelib QuerySet对象转JSON数组的速度

原因说明

原代码耗时高的核心原因有两个:

  1. exchangelib的QuerySet默认是分页懒加载,遍历过程中会逐页发起网络请求拉取数据,默认页大小仅为100条,15万条需要发起1500次网络请求,耗时极高
  2. 逐个实例化ORM对象、手动拼接字典的操作,对15万级数据量来说本身开销就非常大
优化方案

方案1:直接使用values()方法批量获取字典(最优,可达到秒级转换)

exchangelib的QuerySet原生支持values()方法,不需要遍历ORM实例对象,直接返回符合要求的字典列表,既避免了实例化的高额开销,也不会触发额外的延迟加载请求,是性能最高的方案。

query_filter = Q(sender="xyz@abc.com")
timeLimit = UTC_NOW() - timedelta(hours=1)

# 直接通过values指定返回字段的映射关系,支持双下划线取关联属性
MailsArray = list(account.inbox.all().filter(
    query_filter,
    datetime_received__gt=timeLimit
).values(
    Subject="subject",
    ID="conversation_id__id"
))

如果需要输出JSON字符串,直接对结果调用json.dumps(MailsArray)即可。

方案2:调整分页大小+列表推导式处理(适用于有自定义处理逻辑的场景)

如果有values()无法满足的自定义处理逻辑,可以先调整分页大小一次性拉取全量数据到本地,再用列表推导式替代普通for循环,性能提升至少5~10倍。

query_filter = Q(sender="xyz@abc.com")
timeLimit = UTC_NOW() - timedelta(hours=1)

# 调整page_size大于结果集总量,一次性拉取所有数据,避免多次网络请求
Inbox_mails = list(account.inbox.all().filter(
    query_filter,
    datetime_received__gt=timeLimit
).only('subject','conversation_id').page_size(200000))

# 列表推导式比for循环append效率高很多
MailsArray = [{"Subject":x.subject, "ID":x.conversation_id.id} for x in Inbox_mails]
注意事项
  • 不要在遍历过程中访问没有在only()/values()里声明的字段,否则会触发单条数据的延迟查询,大幅增加耗时
  • 15万条数据的JSON序列化可以直接用标准库json模块,如果需要更快的速度可以安装使用ujson替代标准库json

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 04:54:04