使用“Insert或Ignore”语句加快Python执行速度

2024-09-27 07:18:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我是pyodbc的新手,遇到的问题是executemany需要相当长的时间。在对脚本进行基准测试时,将962行插入一个表大约需要15分钟。如果可能的话,我想加快这个查询的速度

我运行以下脚本:

cursor = conn.cursor()
parsed_json = get_parsed_json_Event_Log()
print(f'Gathering data from API found {len(parsed_json)} entries')

cursor.fast_executemany=True
cursor.executemany(f"""
                        IF NOT EXISTS (SELECT 1 FROM {schema_name}.{table_name} WHERE id = ?)
                        INSERT INTO {schema_name}.{table_name}
                        SELECT  ?,
                                ?,
                                DATEADD(s, ?, '19700101 02:00:00:000'),
                                ?,
                                ?,
                                DATEADD(s, ?, '19700101 02:00:00:000'),
                                ?,
                                ?,
                                ?,
                                ?,
                                ?,
                                ?;""", parsed_json)

我正在使用python 3.8.6和Azure SQL Server。解析后的JSON采用pyodbc文档建议的指定序列格式。DATEADD函数中的强制转换日期信息以全局秒为单位提供

我试图实现一个INSERTIGNORE INTO语句,我知道这在SQLite中是可能的。不幸的是,我无法提出Azure SQL Server的实现,因此必须默认为IF NOT EXISTS语句

如果有人能帮助我加快脚本速度或改进语句以加快执行速度,那就太棒了


Tags: name脚本jsonifschemaexistsnot语句
1条回答
网友
1楼 · 发布于 2024-09-27 07:18:48

我多次尝试加快查询速度,并收集了一些见解,希望与所有可能遇到相同问题的人分享:

外卖:

  1. 在使用Azure SQL Server时,请始终尝试使用INSERT INTO ... VALUES (...)语句而不是INSERT INTO ... SELECT ...,因为它的执行速度快了大约350%(在针对所描述的问题和使用的语法进行基准测试时)。
    • 我使用INSERT INTO ... SELECT ...的主要原因是因为特定的DATEADD()强制转换,因为如果不在Azure SQL Server中显式声明变量,就无法做到这一点
  2. 如果将提供的时间强制转换为python datetime,则可以跳过给定示例中的DATEADD()。如果选择此选项,请确保在将数据插入SQL表时不使用文字字符串。除了@Charlieface所述的糟糕做法外,PYODBC在使用字符串文字输入时,没有该数据类型的内置逻辑(这里的序列输入结构没有问题)
  3. IF NOT EXISTS语句非常昂贵。如果可能的话,尽量省略它。如果依赖于历史保存表,一个简单的解决方法是创建新创建的第二个表,然后从该表插入到未找到匹配项的原始表。在这里,您可以依赖本机SQL实现而不是PYODBC实现。这条路是迄今为止最快的

不同的设计选择导致以下性能改进:

  • INSERT INTO ... SELECT ...对{}:350%
  • 利用第二个表和本机SQL支持:560%

相关问题 更多 >

    热门问题