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

为什么服务器负载测试中异步实现比同步写法性能慢数百倍?

核心问题

  1. 错误复用AsyncSession执行并发查询
    SQLAlchemy的AsyncSession是非并发安全对象,同一时间只能执行一个异步操作。你将4个同session的查询丢给asyncio.gather执行,会触发大量内部锁等待、状态校验开销,甚至会导致查询排队超时,性能远低于同步顺序执行。
  2. 开启了调试日志
    两个数据库引擎都配置了echo=True,会打印所有SQL执行日志,异步pg驱动asyncpg的日志打印开销远高于同步驱动psycopg2,高并发下会严重拖慢性能。
  3. 连接池配置不足
    默认异步引擎的连接池大小仅为5,你用100并发压测时,大量请求拿不到数据库连接排队等待,进一步拉低性能,甚至导致请求超时。

优化方案

  • 第一步:关闭调试日志
    修改两个引擎的echo=True为echo=False。
  • 第二步:修正异步查询逻辑
    如果不需要并行查询,直接按同步逻辑的顺序执行即可,不要强行用asyncio.gather,修正后的代码如下:
async def get(self):
    async with async_session() as session:
        result1 = await session.execute(text('SELECT * from *** where client_id = :bis_id').bindparams(bis_id='bis1'))
        self.write(json.dumps(result1.fetchall(), default=str))
        result2 = await session.execute(text('SELECT * from *** where bis_id = :bis_id').bindparams(bis_id='bis1'))
        self.write(json.dumps(result2.fetchall(), default=str))
        result3 = await session.execute(text('SELECT * from *** where abs_id = :abs_id').bindparams(abs_id='abs1'))
        self.write(json.dumps(result3.fetchall(), default=str))
        result4 = await session.execute(text('SELECT * from *** where abs_id = :abs_id').bindparams(abs_id='abs1'))
        self.write(json.dumps(result4.fetchall(), default=str))

如果要实现真正的并行查询,需要每个查询单独创建Session:

async def exec_query(query: text, params: dict):
    async with async_session() as session:
        res = await session.execute(query.bindparams(**params))
        return res.fetchall()

async def get(self):
    results = await asyncio.gather(
        exec_query(text('SELECT * from *** where client_id = :bis_id'), {"bis_id": "bis1"}),
        exec_query(text('SELECT * from *** where bis_id = :bis_id'), {"bis_id": "bis1"}),
        exec_query(text('SELECT * from *** where abs_id = :abs_id'), {"abs_id": "abs1"}),
        exec_query(text('SELECT * from *** where abs_id = :abs_id'), {"abs_id": "abs1"}),
    )
    for res in results:
        self.write(json.dumps(res, default=str))
  • 第三步:调整连接池配置
    创建异步引擎时调整连接池参数匹配压测并发数:
async_engine = create_async_engine(
    "postgresql+asyncpg://***:***@localhost:5431/***",
    echo=False,
    pool_size=20,
    max_overflow=100
)

优化完成后重新压测,异步接口的QPS会恢复到至少和同步接口持平的水平,更高并发场景下性能会优于同步实现。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 13:54:05