2011-12-28 77 views
5

我使用Django /阿帕奇/ sqlite3的,我有一個Django的模型,看起來像這樣:提高Django的數據庫查詢性能

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

我試圖獲得最後300個Temp_entry物品放入一張圖。我這樣做:

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

但是,這個查詢需要約1秒。有沒有辦法改善這一點?我挖了一遍,發現order_by是無效的,所以我希望有一個可行的選擇?

另一個我想到的,但無法弄清楚如何實現的方法是每20分鐘運行一次查詢並保存它,這也是可以接受的,因爲數據可以稍微陳舊,沒有病態效果。

回答

6

如果caching是可以接受的,它總是應該使用。喜歡的東西:

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 

您也可以設置db_indexes爲適當的列

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

謝謝阿列克謝,兩個後續問題:有沒有辦法讓查詢每20分鐘運行一次,而不是等待請求來檢查它是否陳舊? db_indexes是做什麼的? – Andy 2011-12-28 07:48:49

+1

Andy,db_index只是創建普通的數據庫索引,這將提高查詢速度。然而,與高速緩存相比,這種加速沒有任何意義。還要注意像Mysql和Postgre這樣的DB有查詢的內部緩存,但不確定關於sqlite。根據第一個問題:是的,你可以使用django命令和類似cron或芹菜的東西,但我認爲這不是很好的解決方案 – 2011-12-28 09:17:26

+0

謝謝阿列克謝,使用索引和緩存視圖渲染在一個可接受的時間量 – Andy 2011-12-28 16:26:21

-1

好吧,如果你知道你的項目總是有一個增加的日期時間(即在創建條目時的日期時間設置和未編輯),那麼您不必按dateTime排序,因爲它們自然會按照數據庫中的順序排列。

2

您可能需要在數據庫中添加更多索引。使用django-debug工具欄來獲取正在運行的實際查詢的SQL,並使用EXPLAIN功能來顯示它正在使用的索引。對於這個特定的查詢,我想象你需要在(sensor, dateTime)上添加一個索引 - 直接在數據庫shell中執行。

+0

在另一個評論OP的這個主題提出了一個關於索引做什麼的問題。我以爲我會爲你指出這一點。 – Droogans 2011-12-28 11:57:21