2011-12-28 17 views
5

Używam Django/apache/sqlite3 i mam model Django, który wygląda tak:Poprawa wydajności Django DB zapytania

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

Próbuję dostać ostatnich 300 Temp_entry przedmiotów do umieszczenia w wykres. Robię to w ten sposób:

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

Jednak zapytanie to trwa ~ 1 sekundę. Czy istnieje sposób, aby to poprawić? Wykopałem i okazało się, że order_by jest okropnie nieefektywne, więc mam nadzieję, że istnieje realna alternatywa?

Alternatywą, o której myślałem, ale nie potrafię wymyślić, jak ją wdrożyć, byłoby uruchamianie zapytania co 20 minut i przechowywanie go w pamięci podręcznej, co byłoby również do zaakceptowania, ponieważ dane mogą być nieco nieaktualne bez żadnych problemów ruchomości.

Odpowiedz

6

Jeśli akceptowalne jest caching, należy go zawsze używać. Coś jak:

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 

Ponadto można ustawić db_indexes do odpowiednich kolumn

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

Dzięki Alexey, dwa pytania uzupełniające: czy istnieje sposób na uruchamianie zapytania co 20 minut zamiast oczekiwania na żądanie sprawdzenia, czy jest nieaktualny? Co robi db_indeksy? – Andy

+1

Andy, db_index tworzy zwykły indeks bazy danych, który zwiększy prędkość zapytania. Jednak to przyspieszenie jest niczym w porównaniu z buforowaniem. Zauważ również, że takie bazy danych, jak MySQL i Postgre, mają wewnętrzne buforowanie zapytań, ale nie masz pewności co do sqlite. Zgodnie z pierwszym pytaniem: tak, możesz użyć polecenia django i czegoś takiego jak cron lub seler, ale myślę, że to nie jest dobre rozwiązanie –

+0

Dzięki Alexey, używanie indeksów i buforowanie widoku renderuje się w akceptowalnym czasie – Andy

-1

Cóż, jeśli wiesz, że Twoje wpisy zawsze mają coraz dateTime (tj dateTime jest ustawiany, gdy wejście jest tworzony i nie edytowane), to nie musisz zamawiać według dateTime, ponieważ będą one naturalnie w tej kolejności w bazie danych.

2

Prawdopodobnie musisz dodać więcej indeksów do swojej bazy danych. Użyj paska narzędzi django-debug, aby uzyskać SQL rzeczywistego zapytania, które jest uruchamiane, i użyj funkcji WYJAŚNIJ, aby wyświetlić indeksy, których używa. Dla tego konkretnego zapytania, wyobrażam sobie, że musisz dodać indeks na (sensor, dateTime) - zrób to bezpośrednio w powłoce bazy danych.

+0

w innym komentarzu W tym wątku OP zadał pytanie o to, co robi indeks. Myślałem, że wskażę ci to. – Droogans

Powiązane problemy