asyncpg - 连接与连接池

urs*_*san 6 python

我正在asyncpg查看文档,我无法理解为什么使用连接池而不是单个连接.

给出示例中,使用了一个池:

async with pool.acquire() as connection:
    async with connection.transaction():
        result = await connection.fetchval('select 2 ^ $1', power)
        return web.Response(
            text="2 ^ {} is {}".format(power, result))
Run Code Online (Sandbox Code Playgroud)

但也可以通过在必要时创建连接来完成:

connection = await asyncpg.connect(user='postgres')
async with connection.transaction():
    result = await connection.fetchval('select 2 ^ $1', power)
    return web.Response(
            text="2 ^ {} is {}".format(power, result))
Run Code Online (Sandbox Code Playgroud)

根据需要使用池而不是连接有什么好处?

Elv*_*hus 14

建立与数据库服务器的连接是一项昂贵的操作.连接池是一种常见的技术,可以避免支付这笔费用.游泳池保持连接打开,并在必要时出租.

通过简单的基准测试很容易看到池的好处:

async def bench_asyncpg_con():
    power = 2
    start = time.monotonic()
    for i in range(1, 1000):
        con = await asyncpg.connect(user='postgres', host='127.0.0.1')
        await con.fetchval('select 2 ^ $1', power)
        await con.close()

    end = time.monotonic()
    print(end - start)
Run Code Online (Sandbox Code Playgroud)

以上在1.568秒内在我的机器上完成.

而池版本:

async def bench_asyncpg_pool():
    pool = await asyncpg.create_pool(user='postgres', host='127.0.0.1')
    power = 2
    start = time.monotonic()
    for i in range(1, 1000):
        async with pool.acquire() as con:
            await con.fetchval('select 2 ^ $1', power)

    await pool.close()
    end = time.monotonic()
    print(end - start)
Run Code Online (Sandbox Code Playgroud)

运行0.234秒,或快6.7倍.