我正在向一个sqlite数据库写入大量数据。我正在使用一个临时的数据框架来寻找唯一的值。
这条 sql 语句在 conn.execute(sql)
if upload_to_db == True:
print(f'########################################WRITING TO TEMP TABLE: {symbol} #######################################################################')
master_df.to_sql(name='tempTable', con=engine, if_exists='replace')
with engine.begin() as cn:
sql = """INSERT INTO instrumentsHistory (datetime, instrumentSymbol, observation, observationColName)
SELECT t.datetime, t.instrumentSymbol, t.observation, t.observationColName
FROM tempTable t
WHERE NOT EXISTS
(SELECT 1 FROM instrumentsHistory f
WHERE t.datetime = f.datetime
AND t.instrumentSymbol = f.instrumentSymbol
AND t.observation = f.observation
AND t.observationColName = f.observationColName)"""
print(f'##############################################WRITING TO FINAL TABLE: {symbol} #################################################################')
cn.execute(sql)
运行这个要花很长时间才能写到数据库。谁能帮我了解一下如何加快速度?
编辑1.请问你是怎么写的?
大概有多少行?-一次大概15000行。基本上是把数据拉到pandas的数据框里,然后做一些转换,再写到sqlite数据库里,大概有600个不同的仪器,每个仪器大概有15000行,所以最终有9M行。大概有600个不同的仪器,每个仪器大概有15,000行,所以最终有9M行。
根据你的SQL数据库,你可以尝试使用类似于 INSERT INTO IGNORE
(MySQL),或 MERGE
(例如在Oracle上),只有在不违反主键或唯一约束的情况下才会进行插入。 这将假设这样的约束存在于你正在检查的4列上。
在没有合并的情况下,你可以尝试将下面的索引添加到数据库中。instrumentsHistory
表。
CREATE INDEX idx ON instrumentsHistory (datetime, instrumentSymbol, observation,
observationColName);
这个索引可以快速查询每一条来自于 tempTable
因此可能会加快插入过程。
这个子查询
WHERE NOT EXISTS
(SELECT 1 FROM instrumentsHistory f
WHERE t.datetime = f.datetime
AND t.instrumentSymbol = f.instrumentSymbol
AND t.observation = f.observation
AND t.observationColName = f.observationColName)
要检查 每一 表中的一行--并匹配四列--直到找到匹配。 在最坏的情况下,没有匹配,必须完成全表扫描。 因此,随着表的大小增加,查询的性能会变差。
正如Tim的回答中提到的,解决方案是在这四列上创建一个索引,以便db能够快速确定是否存在匹配。