合理连接池大小需匹配硬件与负载:min_size设为平均并发的70%~80%,max_size≤数据库max_connections×0.8,避免锁竞争和内存压力;预编译语句、批量操作及分区键显式使用是关键优化手段。

连接池大小必须匹配硬件与负载,不能只看文档默认值
asyncpg 的 create_pool 默认 min_size=10、max_size=10,但这个值在多数生产环境里是错的。CPU核心数、数据库连接上限、单次查询耗时共同决定合理范围。
-
min_size应设为应用平均并发请求数的 70%~80%,比如常驻 20 个并发,就设min_size=16 -
max_size不应超过 PostgreSQL 的max_connections(默认 100),建议留 20% 余量;若应用峰值并发 50,DB 设置了 80 连接,则max_size ≤ 64 - 盲目调高
max_size反而触发 PostgreSQL 的锁竞争或内存压力,实测在 32 核机器上max_size > 48后吞吐量开始下降
预编译语句(prepared statement)对聚合查询提升最明显
重复执行的 GROUP BY、SUM、COUNT 类查询,不加预编译会反复解析执行计划,浪费 CPU。asyncpg 的 conn.prepare() 能把查询计划缓存在服务端,后续调用直接复用。
- 仅对固定结构、参数位置不变的查询有效;动态字段名或
ORDER BY列不能预编译 - 语句缓存大小由
statement_cache_size控制,默认 100,高并发聚合场景建议设为500~1000 - 示例:
stmt = await conn.prepare("SELECT user_id, COUNT(*) FROM events WHERE ts > $1 GROUP BY user_id"),之后用await stmt.fetch(now)调用
批量操作必须用 executemany 或 copy_records_to_table,别手写循环
逐条 fetch() 或 execute() 插入 1000 行,实际发起 1000 次网络往返 + 1000 次协议解析,延迟爆炸。asyncpg 提供两种高效替代:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
-
executemany():适合中小批量(INSERT INTO t (a,b) VALUES ($1,$2),传入元组列表 -
copy_records_to_table():适合大批量(> 10k 行)或含二进制/JSONB 字段,底层走 PostgreSQL COPY 协议,比executemany快 3~5 倍 - 注意:事务内使用
executemany时,失败会回滚全部;而copy_records_to_table失败则整批失败,无部分成功
分区表查询必须显式带上分区键,否则 asyncpg 无法受益
PostgreSQL 分区裁剪(partition pruning)完全依赖查询条件中是否包含分区键(如 created_at 或 region)。asyncpg 本身不干预这个逻辑,它只是忠实地把 SQL 发过去——如果 SQL 没写对,再快的驱动也白搭。
立即学习“Python免费学习笔记(深入)”;
- 错误写法:
SELECT * FROM logs WHERE id = 123(没带created_at),触发全分区扫描 - 正确写法:
SELECT * FROM logs WHERE created_at >= '2026-09-01' AND created_at - 配合
prepare()使用时,分区键必须作为参数占位符(如$1),不能拼在 SQL 字符串里,否则无法缓存
连接池参数、预编译启用、批量方式选择、分区键写法——这四个点任意一个漏掉,都可能让 asyncpg 的性能优势打五折。最容易被忽略的是最后一点:以为用了 asyncpg 就自动优化分区查询,其实它连表结构都不感知,全靠你写的 SQL。


















