为什么Dataframe.to_sql()在行数达到一定数量后变慢?
我有一个非常大的 Pandas
数据框,大约有900万条记录和56列。我想把这些数据加载到一个MSSQL表中,使用的是 Dataframe.to_sql()
方法。但是一次性导入整个数据框经常会出现内存相关的错误。
为了应对这个问题,我开始把数据框分成每批10万条记录,逐批导入。这样做后,我不再遇到错误,但在导入到580万条记录时,代码的运行速度明显变慢了。我使用的代码如下:
maxrow = df.shape[0]
stepsize = 100000
for i in range(0, maxrow, stepsize):
batchstart = datetime.datetime.now()
if i == 0:
if_exists = 'replace'
else:
if_exists = 'append'
df_import = df.iloc[i:i+stepsize]
df_import.to_sql('tablename',
engine,
schema='tmp',
if_exists=if_exists,
index=False,
dtype=dtypes
)
我对每批的时间进行了测量,发现速度有一个明显的拐点:

这些结果对于每批50k、100k和200k条记录基本相同。上传600万条记录大约需要40分钟,而接下来的300万条记录则需要另外2小时20分钟。
我认为这可能是因为MSSQL表的大小,或者是每次上传后某些东西被缓存或保存了。因此,我尝试将数据框推送到两个不同的表中。我还尝试在每次上传后对 SQLALchemy session
使用 expunge_all()
,但都没有效果。
手动在500万条记录后停止导入,并从500万条记录开始用一个新的引擎对象重新启动,也没有帮助。
我已经没有其他想法来解释为什么这个过程会如此显著地变慢,非常希望能得到帮助。
更新
作为最后的手段,我反转了循环,从数据框的最高索引开始上传部分数据,逐步向下循环。
这样做后,每批的时间基本上反转了。所以看起来是数据本身在数据框的后面部分有所不同或更大,而不是连接过载或SQL表变得太大。
感谢所有尝试提供帮助的人,但看来我需要仔细检查数据,看看是什么导致了这个问题。
1 个回答
暂无回答