es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Optimizar solicitud en el bucle FOR

¿Cómo puedo optimizar la siguiente solicitud para eliminar el bucle? El recuento de códigos es varios cientos, por lo que obtengo varias cientos de consultas de base de datos, lo cual es inaceptable.

n = 3
result = []
codes = Target.objects.filter(code__in=['ABC', 'CDE', ...])

for code in codes:
    result.append(Data.objects.select_related('target')
                              .filter(target__code=code)
                              .values('spec', 'spec_type')
                              .order_by('-spec')[:n])

Modelos:

class Data(models.Model):
    target = models.ForeignKey(Target)
    spec_type = models.CharField()
    spec = models.FloatField()

class Target(models.Model):
    code = models.TextField(db_index=True)
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para optimizar la solicitud anterior y eliminar el bucle, se puede hacer uso del operador __in para filtrar los objetos Data con códigos de Target que coincidan con la lista dada. Esto reducirá significativamente el número de consultas a la base de datos. El código optimizado se vería así:

    n = 3
    result = []
    
    codes = Target.objects.filter(code__in=['ABC', 'CDE', ...])
    
    data_objects = Data.objects.select_related('target') \
                               .filter(target__code__in=[code.code for code in codes]) \
                               .order_by('-spec') \
                               .values('spec', 'spec_type', 'target__code')
    
    for code in codes:
        filtered_data = [data for data in data_objects if data['target__code'] == code.code][:n]
        result.append(filtered_data)
    

    En el código optimizado, primero filtramos los objetos Target para obtener los códigos necesarios. Luego, obtenemos todos los objetos Data que coinciden con estos códigos usando el operador __in. Prefetchamos los objetos Target relacionados para evitar consultas adicionales más adelante.

    Después de eso, ordenamos los objetos de datos por spec en orden descendente y obtenemos solo los campos requeridos. Finalmente, iteramos sobre la lista de objetos Target y filtramos los objetos Data por código y elegimos los primeros n registros. Estos registros filtrados se agregan a la lista de resultados finales.

    De esta manera, podemos eliminar el bucle y reducir significativamente el número de consultas a la base de datos.

Comments are closed.