2011-01-11 101 views
2

在django項目中,我只需要緩存一些查詢,因爲服務器的限制,緩存表而不是memcached。在Django中緩存查詢

其中一個查詢看起來是這樣的:

比方說,我有一個Parent對象,裏面有很多Child對象。 我需要存儲簡單查詢parent.childs.all()的結果。

我有沒有問題,一切正常,與一些代碼預期一樣

key = "%s_children" %(parent.name) 
value = cache.get(key) 
if value is None: 
    cache.set(key, parent.children.all(), CACHE_TIMEOUT) 
    value = cache.get(key) 

但有時,只是有時,cache.set什麼也不做,並且,執行cache.set後,cache.get(key)不斷返回None

經過一番測試後,我注意到cache.setparent.children.all().count()的值較高時不起作用。
這意味着如果我在key(例如)600個兒童物品的內部存儲,它工作正常,
但它不適用於1200名子女。

所以我的問題是是否有一個密鑰可以存儲的數據的限制?我如何覆蓋它?




第二個問題:哪種方式是 「更好」,上面的代碼,或以下的?

key = "%s_children" %(parent.name) 
value = cache.get(key) 
if value is None: 
    value = parent.children.all() 
    cache.set(key, value, CACHE_TIMEOUT) 

第二個版本不會導致錯誤cache.set不起作用,所以它可能是一個解決方法,我的問題,但顯然的解決方案。

一般來說,讓我們忘記我的問題,您認爲哪個版本「更好」?

+1

關於更新的代碼:第二個版本更好。每一次設置或獲取的調用都涉及酸洗和base64編碼數據,所以最大限度地減少這些調用會帶來更好的性能。 – Seth 2011-01-11 21:24:36

回答

0

我看到三種可能性。第一個似乎最有可能對我來說,既然你說你與資源約束運行:

  1. 這可能是因爲它需要一個非常長的時間來獲取您的查詢,對其進行編碼,然後存儲它再次 - 只要您的Web服務器進程耗盡內存或超時並在數據保存之前死亡。

  2. 或者,您的數據庫可能對文本列的長度有一些相當小的限制,並且存儲1200個base64編碼的pickle對象超過了此限制。

  3. 也許你的緩存密鑰超過了255個字符。

+0

1.也許,但我不這麼認爲。 2.這聽起來對我來說真的是可能的...... 3.我們可以放棄這個,因爲我的緩存鍵不超過30個字符。 所以,我會去第二個...現在我必須找到一個可能的解決方案... – dolma33 2011-01-11 20:35:56

+0

好吧,解決方案很簡單:不要嘗試緩存1200個數據庫對象!認真 - [page](http://docs.djangoproject.com/en/dev/topics/pagination/)通過它們。 – Seth 2011-01-11 20:49:16

0

關於memcached的時髦的事情 - 它有一個1MB的限制,可以存儲在給定的緩存鍵。您可以配置此限制,但如果您將此默認設置置於您的控制之外,則會影響代碼的可移植性。

請參見 「存儲數據列表」 在這裏:http://code.google.com/p/memcached/wiki/FAQ

2

是您後端的MySQL?

在MySQL中,TEXT字段are limited to 65,000 bytes但django將使用此類型的值字段。

INSERT &如果您的數據太大,UPDATE查詢將無法自動失敗。

我的建議是保持您的數據小。存儲一個完整的QuerySet似乎過分了。你不能只存儲必填字段嗎?

喜歡這個查詢

resultset = parent.children.values_list(*fields).all() 

將獲取所需的領域,而不是完整的實例。