Tengo un problema de tiempo de ejecución con el siguiente código:
# filter start and end date matches = database.objects.filter(start__gte= Start, end__lte= End) # iterate through matches for Item in matches: # filter database again test = database.objects.filter(cm1=Item.cm1, cm2=Item.cm2, cm3=Item.cm3) # compare first item of filter with iterated Item if test[0] == Item: TrueRun = True else: TrueRun = False Tengo una base de datos con alrededor de 80k filas. En un primer paso, filtro las filas que quiero ver, normalmente deberían ser alrededor de 8k. En un segundo paso itero sobre todos estos elementos y verifico si son únicos o los primeros con algunos atributos específicos ( cm1 , cm2 , cm3 ).
El problema ahora es que hago consultas de base de datos de 8k, que en conjunto toman alrededor de 15 minutos. ¿Hay alguna forma de acelerar esto, por ejemplo, usando un dict antes del ciclo que contiene todas las posibilidades de cm1 y sus filas coincidentes?
¡Gracias por tu ayuda!
__________________________
Editar después de comentar
El orden predeterminado de mis modelos es diferente a cómo se usa aquí. En el programa tengo alrededor de 25 modelos y verifico la igualdad en alrededor de 12 de ellos.
El resto del bucle no debería ser interesante, porque antes había otra forma de comprobar TrueRun , que tardaba unos 2 minutos. Lo único que cambió es el interior #-----# Ver aquí:
equalnessList = ['cm1','cm2', 'cm3'] for idx, Item in enumerate(matches): #-----------------# TrueRun = True listTrue = [] for TrueIdx,TrueItem in enumerate(listTrue): EqualCount = 0 for equCrit in equalnessList: if getattr(Item,equCrit)!=getattr(matches[TrueItem],equCrit): EqualCount += 1 if EqualCount == len(equalnessList): TrueRun = False break #------------------# # Some stuff in here, that can't be changed if TrueRun: resDict[getattr(Item,'id')] = [True] listTrue.append(idx) else: resDict[getattr(Item,'id')] = [False]El problema aquí era que no funcionaba bien y no usaba entradas de la base de datos fuera de las fechas filtradas para la verificación.
# filter start and end date matches = database.objects.filter(start__gte=Start, end__lte=End) # iterate through matches for item in matches: # filter database again and get the id of the first element matched first_item = database.objects.filter(cm1=item.cm1, cm2=item.cm2, cm3=item.cm3).values('id').first() # compare first item id with the id of filtered "item" if first_item['id'] == item.id: TrueRun = True else: TrueRun = FalseEs posible que deba modificar esto para que se ajuste a sus requisitos. En particular, debe mantener el orden de clasificación original dentro de cada grupo cm1, cm2, cm3 .
matches = database.objects.filter(start__gte=Start, end__lte=End) all_objects = database.objects.all().order_by('cm1', 'cm2', 'cm3', 'sequence') # replace 'sequence' by field(s) that model is sorted on by default results_dict = {} cm1 = None cm2 = None cm3 = None first = False for obj in all_objects: if (obj.cm1 != cm1) or (obj.cm2 != cm2) or (obj.cm3 != cm3): cm1 = obj.cm1 cm2 = obj.cm2 cm3 = obj.cm3 first = True if obj.start >= Start and obj.end <= End: results_dict[obj.id] = first first = False