为什么这个sql语句超级慢?

问题描述 投票:0回答:1

我正在向一个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行。

python sql sqlalchemy
1个回答
1
投票

根据你的SQL数据库,你可以尝试使用类似于 INSERT INTO IGNORE (MySQL),或 MERGE (例如在Oracle上),只有在不违反主键或唯一约束的情况下才会进行插入。 这将假设这样的约束存在于你正在检查的4列上。

在没有合并的情况下,你可以尝试将下面的索引添加到数据库中。instrumentsHistory 表。

CREATE INDEX idx ON instrumentsHistory (datetime, instrumentSymbol, observation,
                                        observationColName);

这个索引可以快速查询每一条来自于 tempTable因此可能会加快插入过程。


0
投票

这个子查询

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能够快速确定是否存在匹配。

© www.soinside.com 2019 - 2024. All rights reserved.