需要有关使用 pyodbc to_sql 到 sqlserver 的 python pandas 的建议,速度非常慢

问题描述 投票:0回答:2

全部,

我已经搜索了堆栈溢出,但似乎无法弄清楚我在使用 python 3.11.4、pyodbc 4.0.39、sqlalchemy 2.0.20 将行写入 sqlserver 时做错了什么。问题是大约 100k 行需要将近一天半的时间才能插入到表中。该表没有任何索引并且是空的。我希望代码片段能提供一些见解。

谢谢, 杰夫

cn_1 = sa.create_engine('mssql+pyodbc://servername/dbname?driver=ODBC+Driver+17+for+SQL+Server', fast_executemany=True)

df.to_sql(
    "mytable",
    cn_1,
    if_exists="replace",
    index=False,
)

...

python sql-server pandas sqlalchemy pyodbc
2个回答
0
投票

to_sql
函数默认不执行批量插入。为了提高性能,可以尝试在to_sql函数中使用
method='multi'
参数,该函数使用executemany方法进行批量插入。

df.to_sql(
     "mytable",
      cn_1,
      if_exists="replace",
      index=False,
      method='multi'
)

性能缓慢的另一个原因可能是

network latency
server performance
 driver configuration


0
投票

我要在你的代码中更改的第一件事是“to_sql”,虽然这很方便,但速度很慢。我会将其分解为更小的块,然后一次将这些块写入 sql。像这样:

chunk_size = 5000  # or another value
for start in range(0, len(df), chunk_size):
    df.iloc[start:start + chunk_size].to_sql(
        "mytable",
        cn_1,
        if_exists="append",
        index=False,
    )

这会将内存分解成相当大的块,这可能比一次完成所有操作更快。

另一种方法是使用事务将插入分组在一起。不要提交每一行,而是在一大块行之后提交:

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=cn_1)
session = Session()

chunk_size = 5000
for start in range(0, len(df), chunk_size):
    df.iloc[start:start + chunk_size].to_sql(
        "mytable",
        cn_1,
        if_exists="append",
        index=False,
        method="multi",
    )
    session.commit()

最后,“to_sql”函数有一个方法参数,将其设置为“multi”有时可以加快速度:

df.to_sql(
    "mytable",
    cn_1,
    if_exists="replace",
    index=False,
    method="multi",
)
© www.soinside.com 2019 - 2024. All rights reserved.