You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中执行大型SQL文件时如何显示执行进度或耗时

解决方案

一、快速实现耗时统计

如果只是想知道总耗时,不用改核心执行逻辑,直接加时间记录即可:

import time

def runScript(file):
    with open(file,'r') as f:
        sql = f.read()
    ...
    start_time = time.time()
    with conn.cursor() as cursor:
        cursor.execute(sql)
        conn.commit()  # 别漏了提交事务,否则数据不会写入数据库
    end_time = time.time()
    print(f"总耗时: {end_time - start_time:.2f} 秒")

二、高效带进度条的执行方案

逐行执行慢的核心原因是:每调用一次execute就要和数据库做一次网络交互,5万+次交互的开销会把时间拉满。改成批量分组执行,既能保证效率,又能让tqdm正常显示进度:

通用批量执行方案(兼容不同表的INSERT)

import time
from tqdm import tqdm

def runScript(file, batch_size=1000):
    # 读取并拆分SQL语句(按分号分隔,过滤空行)
    with open(file, 'r') as f:
        sql_content = f.read()
    sql_statements = [stmt.strip() for stmt in sql_content.split(';') if stmt.strip()]
    
    start_time = time.time()
    with conn.cursor() as cursor:
        # 关闭自动提交,用事务减少数据库交互开销
        conn.autocommit = False
        # 分批次遍历,用tqdm显示进度
        for i in tqdm(range(0, len(sql_statements), batch_size), desc="执行进度"):
            batch = sql_statements[i:i+batch_size]
            for stmt in batch:
                cursor.execute(stmt)
            conn.commit()  # 每批次提交一次事务
        conn.autocommit = True
    end_time = time.time()
    print(f"总耗时: {end_time - start_time:.2f} 秒")

同表INSERT的极致优化(多值INSERT)

如果所有INSERT都是针对同一张表的,把多条INSERT合并成单条多值INSERT,效率会再提升一个档次:

import time
from tqdm import tqdm

def runScript(file, batch_size=1000):
    # 读取所有INSERT行(过滤空行和非INSERT语句)
    with open(file, 'r') as f:
        insert_lines = [line.strip() for line in f if line.strip() and line.startswith('INSERT')]
    
    # 提取表结构(从第一条INSERT获取表名和列信息)
    first_line = insert_lines[0]
    table_info = first_line.split('VALUES')[0].strip()  # 得到类似 "INSERT INTO user(id, name)" 的内容
    
    start_time = time.time()
    with conn.cursor() as cursor:
        conn.autocommit = False
        for i in tqdm(range(0, len(insert_lines), batch_size), desc="执行进度"):
            batch_lines = insert_lines[i:i+batch_size]
            # 提取每条INSERT的VALUES部分
            values = [line.split('VALUES')[1].strip().rstrip(';') for line in batch_lines]
            # 拼接成单条多值INSERT语句
            batch_sql = f"{table_info} VALUES {','.join(values)};"
            cursor.execute(batch_sql)
            conn.commit()
        conn.autocommit = True
    end_time = time.time()
    print(f"总耗时: {end_time - start_time:.2f} 秒")

三、终极效率优化:用数据库原生导入工具

如果场景允许,直接用数据库自带的批量导入工具,耗时能从小时级降到分钟/秒级:

  • MySQL:使用LOAD DATA INFILE命令,把数据转成CSV后直接导入
  • PostgreSQL:使用COPY命令
  • SQL Server:使用BULK INSERT命令
    这些工具是数据库层面的原生优化,跳过了Python和数据库的多次交互,效率碾压Python执行INSERT。

内容的提问来源于stack exchange,提问作者Walucas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 18:55:26