2011-12-28 14 views
5

estoy usando Django/Apache/sqlite3 y tengo un modelo de Django que tiene este aspecto:Mejorar el rendimiento de la consulta de Django DB

class Temp_entry(models.Model): 
    dateTime = models.IntegerField() #datetime 
    sensor = models.IntegerField() # id of sensor 
    temp = models.IntegerField()  # temp as temp in Kelvin * 100 

que estoy tratando de conseguir los últimos 300 artículos Temp_entry a colocar en un gráfico. Lo hago de esta manera:

revOutsideTempHistory = Temp_entry.objects.filter(sensor=49).order_by('dateTime').reverse()[:300] 

Sin embargo, esta consulta toma ~ 1 segundo. ¿Hay alguna manera de mejorar esto? He buscado y he encontrado que order_by es terriblemente ineficiente, ¿así que espero que haya una alternativa viable?

Una alternativa que pensé, pero no puedo entender cómo implementarla, sería ejecutar la consulta cada 20 minutos y mantenerla en la memoria caché, eso también sería aceptable, ya que los datos pueden estar un poco añejos sin problemas efectos.

Respuesta

6

Si caching es aceptable, siempre se debe utilizar. Algo así como:

from django.core.cache import cache 

cached = cache.get('temp_entries') 
if cached: 
    result = cached 
else: 
    result = Temp_entry.objects.filter(sensor=49).order_by('dateTime').reverse().values_list()[:300] 
    cache.set('temp_entries', result, 60*20) # 20 min 

También puede establecer db_indexes de las columnas correspondientes

class Temp_entry(models.Model): 
    dateTime = models.IntegerField(db_index=True) #datetime 
    sensor = models.IntegerField(db_index=True) # id of sensor 
    temp = models.IntegerField()  # temp as temp in Kelvin * 100 
+0

Gracias Alexey, dos preguntas de seguimiento: ¿hay alguna manera de que la consulta se ejecute cada 20 minutos en lugar de esperar que la solicitud compruebe si está obsoleta? ¿Qué hace el db_indexes? – Andy

+1

Andy, db_index solo crea un índice de base de datos normal, lo que aumentará la velocidad de una consulta. Sin embargo, esta aceleración no es nada en comparación con el almacenamiento en caché. También tenga en cuenta que tales DB como Mysql y Postgre tienen caché interno de consultas, pero no están seguros acerca de sqlite. Según la primera pregunta: sí, puedes usar el comando django y algo así como cron o apio, pero creo que esta no es una buena solución –

+0

Gracias Alexey, usando los índices y el almacenamiento en caché, la vista se está procesando en un tiempo aceptable – Andy

-1

Bueno, si conoce sus entradas siempre tienen un fechaHora creciente (es decir, el fechaHora se establece cuando se crea la entrada y no editado), entonces no tiene que ordenar por fechaTiempo, ya que naturalmente estarán en ese orden en la base de datos.

2

Probablemente necesite agregar algunos índices más en su base de datos. Use la barra de herramientas django-debug para obtener el SQL de la consulta real que se está ejecutando, y use la función EXPLAIN para mostrar qué índices está usando. Para esta consulta en particular, me imagino que necesitas agregar un índice en (sensor, dateTime) - hazlo directamente en el shell de la base de datos.

+0

en otro comentario este hilo OP hizo una pregunta sobre lo que hace un índice. Pensé que te lo señalaría. – Droogans

Cuestiones relacionadas