表現我設計一個data-tables
驅動的Django應用程序,並有data-tables
電話與AJAX(我使用其服務器端處理模式data-tables
)的API視圖。它實現搜索,分頁和排序。在Django視圖狀態保持改善分頁
我的數據庫最近變大了(大約500,000個條目),性能受到很大影響,無論是搜索還是轉到下一頁。我懷疑我寫這個觀點的方式是非常低效的。下面是我在視圖中執行(假設在我的數據庫中的對象是比薩):
filtered = Pizza.objects.filter(...)
獲得一系列符合搜索條件的比薩餅。 (或者如果沒有搜索標準,則爲Pizza.objects.all()
)。paginated = filtered[start: start + length]
只得到當前的比薩餅頁面。 (最多隻有100個)。根據用戶所在的頁面,從data-tables
客戶端代碼傳入開始和長度。pizzas = paginated.order_by(...)
將排序應用於當前頁面。
然後我將pizzas
轉換成JSON並從視圖中返回它們。
看起來,儘管搜索對於500,000個條目來說可能是一個緩慢的操作,但移動到下一個頁面不應該要求我們重做整個搜索。所以我想要做的是在視圖中緩存一些東西(這是一個基於類的視圖)。我會跟蹤最後一個搜索字符串是什麼,以及它生成的一組結果。
然後,如果請求通過並且搜索字符串沒有不同(如果用戶點擊了幾頁結果,會發生什麼情況),我不必再次點擊數據庫以獲取過濾器結果 - 我只能使用緩存版本。
這是一個只讀應用程序,所以不同步不會是一個問題。
我甚至可以保留一大堆搜索字符串和他們應該產生的比薩餅的字典。
我想知道的是:這是對問題的合理解決方案嗎?還是有我忽略的東西?另外,我在這裏重新發明車輪嗎?這並不是說這不易實施,但是QuerySet
還有一個內置的選項,或者可以做到這一點?
哇,這是真的嗎?如果我先切片查詢集,然後做過濾/排序/無論它,它實際上是過濾/命令/任何然後切片? –
根據django 1.8的文檔,「對未評估的QuerySet進行切片會返回另一個未評估的QuerySet,因此不允許對其進行進一步修改(例如,添加更多過濾器或修改排序)」。所以看起來我部分錯了,'pizzas = paginated.order_by(...)'是不允許的。仍然「考慮將索引添加到您經常使用filter(),exclude(),order_by()查詢的字段」 – JimmyYe