SQLAlchemy 批量插入性能对比分析

SQLAlchemy 批量插入性能对比分析

sqlalchemy The Database Toolkit for Python sqlalchemy 项目地址: https://gitcode.com/gh_mirrors/sq/sqlalchemy

前言

在数据库操作中,批量插入数据是一个常见的性能优化场景。SQLAlchemy 作为 Python 中强大的 ORM 工具,提供了多种批量插入数据的方式。本文将通过 SQLAlchemy 的示例代码,深入分析不同批量插入方法的性能特点和使用场景。

测试环境准备

示例代码中定义了一个简单的 Customer 模型类,包含 id、name 和 description 三个字段。测试将对比插入 10 万条记录时不同方法的性能表现。

class Customer(Base):
    __tablename__ = "customer"
    id = Column(Integer, Identity(), primary_key=True)
    name = Column(String(255))
    description = Column(String(255))

六种批量插入方法对比

1. 传统 ORM 方式(无主键)

def test_flush_no_pk(n):
    """ORM 批量插入,自动生成主键"""
    session = Session(bind=engine)
    for chunk in range(0, n, 1000):
        session.add_all([...])
        session.flush()
    session.commit()

特点

  • 使用标准 ORM 工作流程
  • 每次 flush 会生成并执行 SQL
  • 需要数据库返回生成的主键值
  • 性能相对较低,适合小批量数据插入

2. 传统 ORM 方式(指定主键)

def test_flush_pk_given(n):
    """ORM 批量插入,预先指定主键"""
    session = Session(bind=engine)
    for chunk in range(0, n, 1000):
        session.add_all([...])
        session.flush()
    session.commit()

特点

  • 相比无主键版本性能略好
  • 避免了主键值的获取开销
  • 仍然需要维护 ORM 对象状态

3. ORM 批量插入(不返回对象)

def test_orm_bulk_insert(n):
    """ORM 批量插入,不返回对象"""
    session = Session(bind=engine)
    session.execute(insert(Customer), [...])
    session.commit()

特点

  • 使用 ORM 的批量插入功能
  • 不返回插入的对象实例
  • 性能优于传统 ORM 方式
  • 适合不需要操作插入后对象的场景

4. ORM 批量插入(返回对象)

def test_orm_insert_returning(n):
    """ORM 批量插入,返回新对象"""
    session = Session(bind=engine)
    customer_result = session.scalars(insert(Customer).returning(Customer), [...])
    customers = customer_result.all()
    session.commit()

特点

  • 使用 RETURNING 子句获取插入数据
  • 返回完整的 ORM 对象
  • 性能比不返回对象版本稍差
  • 适合需要操作插入后对象的场景

5. 核心层批量插入

def test_core_insert(n):
    """核心层批量插入"""
    with engine.begin() as conn:
        conn.execute(Customer.__table__.insert(), [...])

特点

  • 绕过 ORM 直接使用核心层
  • 性能优于 ORM 方式
  • 不涉及对象状态管理
  • 适合纯数据插入场景

6. 原始 DBAPI 批量插入

def test_dbapi_raw(n):
    """原始 DBAPI 批量插入"""
    conn = engine.pool._creator()
    cursor = conn.cursor()
    compiled = Customer.__table__.insert().compile(dialect=engine.dialect)
    cursor.executemany(str(compiled), list(args))
    conn.commit()
    conn.close()

特点

  • 直接使用底层数据库 API
  • 性能最佳
  • 需要手动处理连接和游标
  • 代码复杂度最高

性能对比结论

根据测试方法的设计,我们可以预期性能从低到高排序大致为:

  1. 传统 ORM 方式(无主键)
  2. 传统 ORM 方式(指定主键)
  3. ORM 批量插入(返回对象)
  4. ORM 批量插入(不返回对象)
  5. 核心层批量插入
  6. 原始 DBAPI 批量插入

实际应用建议

  1. 需要完整 ORM 功能:选择传统 ORM 方式,牺牲部分性能换取便利性
  2. 大批量插入不关心对象:优先使用核心层批量插入
  3. 极致性能需求:考虑原始 DBAPI 方式
  4. 需要插入后对象但数据量大:使用 ORM 批量插入并返回对象

注意事项

  1. 批量大小需要根据数据库和网络情况调整
  2. 事务管理对性能有重要影响
  3. 不同数据库后端可能有不同的性能表现
  4. 实际项目中应结合业务需求选择合适的方法

通过本文的分析,开发者可以根据具体场景选择最合适的 SQLAlchemy 批量插入方法,在保证功能需求的同时获得最佳性能。

sqlalchemy The Database Toolkit for Python sqlalchemy 项目地址: https://gitcode.com/gh_mirrors/sq/sqlalchemy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时翔辛Victoria

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值