主要观点:简单的插入查询在流量增长时变成了性能杀手,高并发下失败的插入会引入意外开销,如事务回滚和表膨胀,可通过ON CONFLICT DO NOTHING
让 PostgreSQL 处理冲突来解决。
关键信息:前端每分钟ping服务器以跟踪设备活动,插入到DevicePingDaily
表,有唯一约束,Django 逻辑看似无害但流量大时 latency 飙升和 API 超时增加,观察工具指出是单个 INSERT 导致 10 分钟数据库时间,根源是大规模插入失败,包括事务回滚和死元组及表膨胀,有两种解决方法,一是bulk_create(..., ignore_conflicts=True)
,二是原生 SQL 避免 ORM 开销和事务包装,部署后查询时间从 10 分钟降至几秒,autovacuum 活动为零,API 超时消失。
重要细节:DevicePingDaily
表有(device_id, date)
唯一约束,高并发下插入大多冲突,失败插入会导致事务回滚,每次回滚虽便宜但多次重复昂贵,失败插入会留下死元组占用磁盘空间导致表膨胀和索引变慢,autovacuum 运行频繁,bulk_create
可通过ignore_conflicts=True
处理冲突,原生 SQL 可直接使用ON CONFLICT DO NOTHING
且能更好控制冲突处理,部署后性能显著提升。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。