全部,
我已经搜索了堆栈溢出,但似乎无法弄清楚我在使用 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,
)
...
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
我要在你的代码中更改的第一件事是“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",
)