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

如何高效将DataFrame插入MySQL表?解决插入慢与重复行问题

高效批量插入DataFrame到MySQL并跳过重复行

你当前的逐行插入效率极低,核心问题是每次循环都要发起一次数据库请求,开销极大;而直接批量插入遇到重复行就整体失败,是因为默认的INSERT语句只要有一行重复就会终止整个批次。下面是几个远优于转列表循环的解决方案:

方案1:利用SQLAlchemy的MySQL原生插入语法(推荐)

通过sqlalchemy.dialects.mysql.insert构造带重复处理逻辑的批量插入语句,既能保证批量插入的效率,又能自动跳过或更新重复行:

from sqlalchemy.dialects.mysql import insert

# 将DataFrame转为字典列表(批量插入的数据源)
data_records = mydf.to_dict('records')

# 构造插入语句,指定表名和数据源
insert_stmt = insert(save_table).values(data_records)

# 遇到重复键时忽略该行(如果需要更新重复行,可改为on_duplicate_key_update(列名=值))
on_duplicate_stmt = insert_stmt.on_duplicate_key_update()

# 执行批量插入
with my_engine.connect() as conn:
    conn.execute(on_duplicate_stmt)

这个方案直接利用MySQL的原生能力,批量执行的效率比逐行插入高几个数量级,且只会跳过重复行,不影响其他行的插入。

方案2:自定义to_sql的插入方法

如果想继续使用pandas.to_sql,可以自定义插入方法,在语句中加入INSERT IGNORE来跳过重复行:

def insert_ignore_with_batch(table, conn, keys, data_iter):
    # 构造带IGNORE的批量插入语句
    insert_sql = f"INSERT IGNORE INTO `{table.schema}`.`{table.name}` ({','.join(f'`{k}`' for k in keys)}) VALUES ({','.join(['%s']*len(keys))})"
    # 批量执行
    conn.executemany(insert_sql, data_iter)

# 调用to_sql时使用自定义方法
mydf.to_sql(
    name=save_table,
    con=my_engine,
    schema='my_schema',
    index=False,
    if_exists='append',
    method=insert_ignore_with_batch
)

这个方法通过executemany批量提交数据,同时INSERT IGNORE会自动忽略违反唯一约束的行,不会抛出异常终止整个插入流程。

不推荐转列表循环插入的原因

转列表循环本质还是逐行插入,和你当前的iloc[i:i+1].to_sql没有本质区别,依然会因为频繁的数据库交互导致速度极慢,完全没必要采用。

注意事项

确保你的MySQL表已经设置了正确的主键或唯一约束,否则INSERT IGNORE和ON DUPLICATE KEY无法识别重复行,也就起不到作用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:02:41