Pandas to_sql 参数和性能
Pandas to_sql Parameters & Performance
我目前正在尝试稍微调整一些脚本的性能,瓶颈似乎始终是使用 pandas to_sql函数。
其中一个因素是 mssql 的参数限制为 2100。
我与 sqlalchemy 建立了联系(使用 mssql + pyodbc 风格):
engine = sqlalchemy.create_engine("mssql+pyodbc:///?odbc_connect=%s" % params, fast_executemany=True)
插入时我使用块大小(所以我保持在参数限制和方法="multi"以下):
dataframe_audit.to_sql(name="Audit", con=connection, if_exists='append', method="multi",
chunksize=50, index=False)
这会导致以下(不幸的是极其不一致)性能:
我不确定对此有何看法:
- 不一致似乎源于数据库服务器本身
- 更大的块大小似乎并不能转化为更好的性能(似乎恰恰相反!?)
- 也许我应该从 pyodbc 切换到 turbodbc(根据一些帖子,它会产生更好的性能)
有什么想法可以让我的数据帧获得更好的插入性能吗?
如果您在 SQL 服务器和 fast_executemany=True
的 SQLAlchemy create_engine
调用中使用带有 ODBC 驱动程序 17 的最新版本的 pyodbc,那么您应该在 to_sql
调用中使用 method=None
(默认值)。这将允许 pyodbc 使用 ODBC 参数数组并在该设置下为您提供最佳性能。您不会达到 SQL 服务器存储过程 2100 个参数的限制(除非您的 DataFrame 有 ~2100 列)。您将面临的唯一限制是,如果您的 Python 进程在将其发送到 SQL 服务器之前没有足够的可用内存来构建整个参数数组。
to_sql
的 method='multi'
选项仅在使用不支持参数数组的 ODBC 驱动程序(例如 FreeTDS ODBC)时适用于 pyodbc。在那种情况下 fast_executemany=True
将无济于事,实际上可能会导致错误。
我目前正在尝试稍微调整一些脚本的性能,瓶颈似乎始终是使用 pandas to_sql函数。
其中一个因素是 mssql 的参数限制为 2100。
我与 sqlalchemy 建立了联系(使用 mssql + pyodbc 风格):
engine = sqlalchemy.create_engine("mssql+pyodbc:///?odbc_connect=%s" % params, fast_executemany=True)
插入时我使用块大小(所以我保持在参数限制和方法="multi"以下):
dataframe_audit.to_sql(name="Audit", con=connection, if_exists='append', method="multi",
chunksize=50, index=False)
这会导致以下(不幸的是极其不一致)性能:
我不确定对此有何看法:
- 不一致似乎源于数据库服务器本身
- 更大的块大小似乎并不能转化为更好的性能(似乎恰恰相反!?)
- 也许我应该从 pyodbc 切换到 turbodbc(根据一些帖子,它会产生更好的性能)
有什么想法可以让我的数据帧获得更好的插入性能吗?
如果您在 SQL 服务器和 fast_executemany=True
的 SQLAlchemy create_engine
调用中使用带有 ODBC 驱动程序 17 的最新版本的 pyodbc,那么您应该在 to_sql
调用中使用 method=None
(默认值)。这将允许 pyodbc 使用 ODBC 参数数组并在该设置下为您提供最佳性能。您不会达到 SQL 服务器存储过程 2100 个参数的限制(除非您的 DataFrame 有 ~2100 列)。您将面临的唯一限制是,如果您的 Python 进程在将其发送到 SQL 服务器之前没有足够的可用内存来构建整个参数数组。
to_sql
的 method='multi'
选项仅在使用不支持参数数组的 ODBC 驱动程序(例如 FreeTDS ODBC)时适用于 pyodbc。在那种情况下 fast_executemany=True
将无济于事,实际上可能会导致错误。