Python 환경에서 SQLAlchemy를 이용한 DB 애플리케이션을 작성하고 동기적 프로그래밍 또는 비동기적 프로그래밍을 통해 성능을 비교하는 작업을 수행했다. 문자열 필드 하나만을 가지는 테이블에 10만 건의 레코드를 insert하는 애플리케이션을 작성하여 성능 비교에 이용하였다.
대상 DB는 처음에 SQLite를 사용했다가 MySQL로 변경해서 동일한 테스트를 수행했다.
asynchronous의 경우, 한 번의 insert마다 await하는 serial 방식이 있고, 한 번의 insert에 대응되는 coroutine들을 다 만들어 두고 한 번에 모으는 concurrent 방식이 있어서 나눠서 평가하였다.
#!/usr/bin/env python
import asyncio
from sqlalchemy import Column, MetaData, String, Table
from sqlalchemy.ext.asyncio import create_async_engine
meta = MetaData()
t1 = Table("t1", meta, Column("name", String(50), primary_key=True))
async def async_main() -> None:
engine = create_async_engine("sqlite+aiosqlite:///../sqlalchemy_test")
size = 100000
async with engine.begin() as conn:
await conn.run_sync(meta.create_all)
for i in range(size):
await conn.execute(t1.insert(), {"name": f"some name {i}"})
await engine.dispose()
asyncio.run(async_main())
#!/usr/bin/env python
import asyncio
from sqlalchemy import Column, MetaData, select, String, Table
from sqlalchemy.ext.asyncio import create_async_engine
meta = MetaData()
t1 = Table("t1", meta, Column("name", String(50), primary_key=True))
async def async_main() -> None:
engine = create_async_engine("sqlite+aiosqlite:///../sqlalchemy_test")
size = 100000
queries = [None] * size
async with engine.begin() as conn:
await conn.run_sync(meta.create_all)
for i in range(size):
queries[i] = conn.execute(t1.insert(), {"name": f"some name {i}"})
result = await asyncio.gather(*queries)
await engine.dispose()
asyncio.run(async_main())
#!/usr/bin/env python
from sqlalchemy import Column, MetaData, select, String, Table, create_engine
meta = MetaData()
t1 = Table("t1", meta, Column("name", String(50), primary_key=True))
def main() -> None:
engine = create_engine("sqlite:///../sqlalchemy_test")
size = 100000
queries = [None] * size
with engine.begin() as conn:
meta.create_all(engine)
for i in range(size):
queries[i] = conn.execute(t1.insert(), {"name": f"some name {i}"})
engine.dispose()
if __name__ == "__main__":
main()
engine = create_async_engine("mysql+aiomysql://localhost:3306/sqlalchemy", pool_size=10, max_overflow=20)
engine = create_async_engine("mysql+aiomysql://localhost:3306/sqlalchemy", pool_size=10, max_overflow=20)
engine = create_engine("mysql://localhost:3306/sqlalchemy", pool_size=10, max_overflow=20)
| 프로그래밍 방식 | 수행 시간 |
|---|---|
| async/serial | 13.318 |
| async/concurrent | 11.783 |
| sync | 4.045 |
| 프로그래밍 방식 | 수행 시간 |
|---|---|
| async/serial | 10.227 |
| async/concurrent | 14.016 |
| sync | 6.434 |