2011-12-28 14 views
5

sto usando django/apache/sqlite3 e ho un modello di Django che assomiglia a questo:Migliorare le prestazioni di query di 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 

Sto cercando di ottenere gli ultimi 300 articoli Temp_entry per posizionare in un grafico. Lo faccio in questo modo:

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

Tuttavia, questa query richiede ~ 1 secondo. C'è un modo per migliorare questo? Ho scavato e ho trovato che order_by è orribile inefficiente, quindi spero che ci sia un'alternativa valida?

Un'alternativa che ho pensato, ma non riesco a capire come implementare, sarebbe quella di eseguire la query ogni 20 minuti e tenerla memorizzata nella cache, che sarebbe accettabile anche, in quanto i dati possono essere leggermente scaduti senza ammalarsi effetti.

risposta

6

Se caching è accettabile, deve sempre essere utilizzato. Qualcosa di simile:

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 

Inoltre è possibile impostare db_indexes per le colonne appropriate

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

Grazie Alexey, due domande di follow-up: c'è un modo per far funzionare la query ogni 20 minuti invece di aspettare che la richiesta verifichi se è inattiva? Cosa fa il db_indexes? – Andy

+1

Andy, db_index crea semplicemente un indice di database normale, che aumenterà la velocità di una query. Tuttavia, questa velocità non è nulla rispetto al caching. Si noti inoltre che tali DB come Mysql e Postgre hanno il caching interno di query, ma non sono sicuro di sqlite. Secondo la prima domanda: si puoi usare il comando django e qualcosa come cron o celery ma penso che questa non sia una buona soluzione –

+0

Grazie Alexey, usando gli indici e la cache la vista viene resa in un tempo accettabile – Andy

-1

Beh, non so se le voci hanno sempre un dateTime aumento (cioè il dateTime è impostato quando si crea l'ingresso e non modificato), quindi non è necessario ordinare per data. Poiché saranno naturalmente in tale ordine nel database.

2

Probabilmente è necessario aggiungere altri indici nel database. Utilizzare la barra degli strumenti django-debug per ottenere l'SQL della query effettiva in esecuzione e utilizzare la funzione EXPLAIN per mostrare quali indici sta utilizzando. Per questa particolare query, immagino che sia necessario aggiungere un indice su (sensor, dateTime) - farlo direttamente nella shell del database.

+0

in un altro commento su questo thread l'OP ha fatto una domanda su cosa fa un indice. Ho pensato di farlo notare per te. – Droogans

Problemi correlati