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

Django导入CSV文件时for循环处理耗时过长如何优化

Django CSV导入循环逻辑性能优化方案

以下优化按性能提升幅度从高到低排序,修改后1000条记录处理耗时可降到秒级:

核心问题修复

1. 移除循环内重复数据库查询(最大耗时点)

你当前代码每遍历一行CSV,就执行一次AsignacionContact.objects.get(id=self.object.pk),1000行就会发起1000次完全重复的SQL查询,属于典型的N+1查询问题。
实际上self.object.pk是循环全程固定不变的值,且Django外键支持直接通过字段名_id传关联主键值,完全不需要查询关联模型实例,零数据库开销就能完成外键赋值。

错误写法:
idasignacion=AsignacionContact.objects.get(id=self.object.pk)
优化写法(循环外提前定义,全程复用):
asignacion_contact_id = self.object.pk
实例化模型时直接传:idasignacion_id=asignacion_contact_id

2. 删除循环内无意义的调试打印

循环里的print('inicio de for')会在每一行处理时触发标准输出IO,1000行就打印1000次日志,IO开销远高于纯CPU计算,是第二大耗时来源,直接删除即可。

3. 提前做字段类型转换,减少ORM隐式开销

你的模型中corriente_no_vencida_actual、corrente_vencida、total_deuda_corriente、cuota_minima_agente是整数类型字段,但当前代码直接传入CSV读取到的字符串,Django ORM在实例化模型时会自动做类型转换、字段合法性校验,每一行都要跑一遍全字段校验逻辑,累积开销很高。
可以在循环外定义统一的单元格值处理函数,提前做去空格、空值处理、整数转换,减少ORM层的隐式计算。

4. 简化CSV读取逻辑

当前用codecs.iterdecode包装文件流再传给csv.reader,多了一层迭代解码的开销,直接以指定编码打开文件流传给csv.reader即可,减少不必要的迭代包装。

5. 调整批量插入批次大小

你当前设置的5000条一批插入阈值过大,主流关系型数据库单次bulk_create的最优批次是1000-2000条,批次过大会导致单次SQL语句过长,数据库解析开销上升,反而拖慢速度。

优化后完整代码参考

import csv

class AsignacionCreateView(CreateView):
    model=AsignacionContact
    form_class=AsignacionForm
    template_name='gestionAsignacion/asignacion_contact.html'
    success_url = reverse_lazy('gestionAsignacion:asignacion_contact')
    
    def form_valid(self, form):
        isvalid = super().form_valid(form)
        csv_file = self.request.FILES['file']
        # 提前固定外键值,全程无重复查询
        asignacion_contact_id = self.object.pk
        # 定义需要转整数的字段索引
        INT_FIELD_INDEX = {5, 6, 7, 8}
        # 循环外定义值处理函数,避免重复创建函数开销
        def parse_cell(idx, raw_val):
            val = raw_val.strip() if raw_val else None
            if not val:
                return None
            if idx in INT_FIELD_INDEX:
                return int(val)
            return val

        asignaciones = []
        # 简化CSV读取逻辑
        with csv_file.open('r', encoding='utf-8') as f:
            reader = csv.reader(f, delimiter=",")
            next(reader) # 跳过表头
            for row in reader:
                asignacion = AsignacionSur(
                    idasignacion_id=asignacion_contact_id,
                    producto=parse_cell(0, row[0]),
                    contrato=parse_cell(1, row[1]),
                    nombre_suscriptor=parse_cell(2, row[2]),
                    tipo_servicio=parse_cell(3, row[3]),
                    total_deuda=parse_cell(4, row[4]),
                    corriente_no_vencida_actual=parse_cell(5, row[5]),
                    corrente_vencida=parse_cell(6, row[6]),
                    total_deuda_corriente=parse_cell(7, row[7]),
                    cuota_minima_agente=parse_cell(8, row[8]),
                    politica_surtigas=parse_cell(9, row[9]),
                    categoria=parse_cell(10, row[10]),
                    estrato=parse_cell(11, row[11]),
                    ref_anio=parse_cell(12, row[12]),
                    historico_ref=parse_cell(12, row[12]),
                    ciclo=parse_cell(14, row[14]),
                    medidor=parse_cell(15, row[15]),
                    lectura=parse_cell(16, row[16]),
                    plan_acuerdo=parse_cell(17, row[17]),
                    descripcion_barrio=parse_cell(18, row[18]),
                    direccion=parse_cell(19, row[19]),
                    dias_deuda=parse_cell(20, row[20])
                )
                asignaciones.append(asignacion)
                # 调整批次大小为1000,适配数据库最优插入性能
                if len(asignaciones) >= 1000:                
                    AsignacionSur.objects.bulk_create(asignaciones)
                    asignaciones = []
            if asignaciones:
                AsignacionSur.objects.bulk_create(asignaciones)              
        return isvalid

额外优化建议

  • 导入操作前临时关闭Django的DEBUG模式,避免框架记录所有SQL查询、请求上下文带来的额外内存和CPU开销。
  • 如果CSV文件超过10万行,不要在web请求中同步处理,改成Celery、Django-Q等异步任务执行,避免请求超时,同时可以给用户展示导入进度。
  • 你的AsignacionSur模型主键是自定义的IntegerField而非自增字段,bulk_create时要确保主键值不重复,避免插入报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 00:15:31