2012-01-05 94 views
2

我正在使用API​​,並且我有一個問題。我正在研究select_related()的用法,以便爲自己節省一些數據庫查詢,事實上它確實有助於減少執行的數據庫查詢的數量,以及更復雜和更復雜的查詢的費用。Django:select_related()和內存使用情況

我的問題是,使用select_related()會導致heasvier內存使用情況?運行一些實驗,我發現確實如此,但我想知道爲什麼。不管我是否使用select_related(),響應將包含完全相同的數據,那麼爲什麼使用select_related()會導致使用更多的內存?

是因爲緩存嗎?也許單獨的數據對象用於緩存相同的模型實例?我不知道還有什麼想法。

在此先感謝。

回答

6

這是一個折衷。將查詢發送到數據庫需要時間,數據庫準備結果,然後將結果發回。 select_related的工作原理是這個過程中最昂貴的部分是請求和響應循環,而不是實際的查詢,所以它允許你將原本不同的查詢合併爲一個,所以只有一個請求和響應,而不是多。但是,如果數據庫服務器電源不足(沒有足夠的RAM,處理能力等),較大的查詢實際上最終可能會比請求和響應週期花費更長的時間。如果出現這種情況,您可能需要升級服務器,而不是使用select_related

經驗法則是,如果您需要相關數據,請使用select_related。如果實際速度不是很快,那麼這就是您需要優化數據庫的一個信號。

UPDATE(添加更多的解釋)

查詢數據庫實際上包括多個步驟:

  1. 應用生成
  2. 查詢被髮送到數據庫服務器(毫秒到查詢(忽略不計)秒)
  3. 數據庫處理查詢(毫秒到秒)
  4. 查詢資源(毫秒到秒)

在調整良好的環境(足夠的服務器資源,快速連接)中,整個過程僅需幾毫秒即可完成。但是,步驟2和步驟4通常比步驟3佔用更多的時間。這就是爲什麼發送比多個更簡單的查詢更少的複雜查詢更有意義:瓶頸通常是傳輸層而不是處理。

但是,對於擁有大型複雜表的動力不足的機器而言,數據庫性能差的數據庫可能需要很長時間才能運行查詢,從而成爲瓶頸。這最終會抵消發送一個複雜查詢而不是多個簡單查詢所帶來的時間減少,即數據庫對較簡單的查詢響應更快,並且整個過程需要更少的淨時間。然而,如果是這種情況,正確的響應是修復數據庫端:優化數據庫及其配置,添加更多的服務器資源等,而不是恢復發送多個簡單查詢。

+0

Chris,謝謝你的迴應。一個後續問題;您提到:如果您的數據庫服務器處於供電狀態,則較大的查詢實際上可能最終花費的時間比請求和響應週期更長。這是什麼原因?請求/響應週期的較大查詢需要多長時間?以及更大的查詢如何消耗更多的內存?謝謝:) – 2012-01-05 22:53:17

+0

「較大」的查詢,我的意思是一個更復雜(涉及連接等),不一定是實際查詢的文本長度。然後數據庫必須繼續做許多額外的工作,從多個來源選擇數據並將它們拼接在一起。另外,如果這些表格有許多列和/或行,可能會增加涉及的時間和處理。如果運行數據庫的系統具有足夠的資源,則不應超過幾毫秒。但是,如果系統電源不足,導致內存溢出和分頁,則可能需要更多時間。 – 2012-01-06 15:20:31

+0

夢幻般的答案:)我希望我可以upvote你更多! – 2012-01-07 12:20:19