使用Python和Pandas的SQLite3在添加大量数据时会变慢
我正在尝试使用Pandas的df.to_sql和python中的SQlite3在一个数据库中放入大约2GB的数据和大约1600万行。我的策略是将原始CSV分块成更小的数据帧,对它们执行一些操作,然后将它们放入SQL数据库 当我运行这段代码时,它的启动速度很快,但速度很快就会减慢。在大约300万行之后,它会减速到这样一个程度,因为它似乎不会在任何实际的时间内完成。这是什么原因?我能做些什么?我的代码如下:使用Python和Pandas的SQLite3在添加大量数据时会变慢,python,database,pandas,sqlite,Python,Database,Pandas,Sqlite,我正在尝试使用Pandas的df.to_sql和python中的SQlite3在一个数据库中放入大约2GB的数据和大约1600万行。我的策略是将原始CSV分块成更小的数据帧,对它们执行一些操作,然后将它们放入SQL数据库 当我运行这段代码时,它的启动速度很快,但速度很快就会减慢。在大约300万行之后,它会减速到这样一个程度,因为它似乎不会在任何实际的时间内完成。这是什么原因?我能做些什么?我的代码如下: def chunk_read_CSV_to_db(database, table, file
def chunk_read_CSV_to_db(database, table, filepath, chunksize, delimiter=','):
start = dt.datetime.now()
conn = sqlite3.connect(database)
index_start = 1
j=0
for df in pd.read_csv(filepath, chunksize=chunksize, iterator=True, encoding='utf-8', sep=delimiter):
j+=1
print '{} seconds: complete {} rows'.format((dt.datetime.now() -start).seconds, j*chunksize)
df.to_sql(name=table, con=conn, flavor='sqlite', if_exists='append')
conn.close()
db_name = 'store_data.db'
f9 = 'xrf_str_geo_ta4_1511.txt'
chunksize = 20000
chunk_read_CSV_to_db(os.path.join(fp, db_name), os.path.splitext(f9)[0], os.path.join(fp, f9), chunksize = chunksize, delimiter='\t')
我改用了sqlalchemy,从那以后时间就没有问题了。没有明显的放缓。代码如下
def chunk_read_CSV_to_db(database, table, filepath, chunksize, delimiter=',', index=False):
start = dt.datetime.now()
index_start = 1
j=0
for df in pd.read_csv(filepath, chunksize=chunksize, iterator=True, encoding='utf-8', sep=delimiter):
j+=1
print '{} seconds: complete {} rows'.format((dt.datetime.now() -start).seconds, j*chunksize)
df.to_sql(table, db, flavor='sqlite', if_exists='append', index=index)
db = create_engine('sqlite:///store_data.db')
meta = MetaData(bind=db)
table_pop = Table('xrf_str_geo_ta4_1511', meta,
Column('TDLINX',Integer, nullable=True),
Column('GEO_ID',Integer, nullable=True),
Column('PERCINCL', Numeric, nullable=True)
)
chunksize = 20000
chunk_read_CSV_to_db(db,'xrf_str_geo_ta4_1511', os.path.join(fp, f9), chunksize = chunksize, delimiter='\t')
解决方案:将
df.to_sql
参数设置为index=False
所以我知道这个答案将不再与作者相关,但我偶然发现了它,因为我有完全相同的问题,并想分享我的答案
我试图使用append方法将~900.csv文件逐个加载到sql数据库中。加载开始得很快,但速度呈指数级下降,从未完成运行。这让我怀疑索引出现了问题(即每次我添加数据时熊猫都会以某种方式重新编制索引),因为这是我唯一能想到的解释减速的方法(内存似乎很好)
最后,我开始通过命令行使用sqlite3.index和.dbinfo方法来查看通过pandas创建的数据库,并与通过sqlite3直接比较的数据库进行比较。我发现pandas数据库在通过sqlite3处理时有1个索引,而不是0。而且,模式的大小要大得多
现在,pandas to_sql方法有一个索引参数。它说这个参数只是将dataframe索引作为列添加到数据库中(这听起来很无害)。但事实证明,它也使用该列作为数据库索引,而且如果您使用的是append方法,那么它可能每次(或其他)都会重新计算该索引。无论如何,当我将index参数设置为False时,.dbinfo在生成的数据帧中显示0个索引,我的问题消失了-所有数据都在很短的时间内处理完毕
因此,解决办法是:
df.to_sql(name=table, con=conn, flavor='sqlite', if_exists='append', index = False)
您的表中有索引吗?最好删除索引,添加数据,然后创建索引。请参阅长话短说:设置
index=False
,您就可以开始了。好的捕获-已更新我的答案,以便提前加载解决方案。