亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Django ORM中的select_related和prefetch_related有什么區別?

Django ORM中的select_related和prefetch_related有什么區別?

慕碼人2483693 2019-10-05 11:12:54
在Django文檔中,select_related() “遵循”外鍵關系,在執行查詢時選擇其他相關對象數據。prefetch_related() 對每個關系進行單獨的查找,并在Python中執行“聯接”。“在python中進行連接”是什么意思?有人可以舉例說明嗎?我的理解是,對于外鍵關系,使用select_related; 對于M2M關系,請使用prefetch_related。這個對嗎?
查看完整描述

3 回答

?
繁星點點滴滴

TA貢獻1803條經驗 獲得超3個贊

兩種方法可以達到相同的目的,從而放棄不必要的數據庫查詢。但是他們使用不同的方法來提高效率。


使用這兩種方法的唯一原因是,當單個大型查詢優于許多小型查詢時。Django使用大型查詢來搶先在內存中創建模型,而不是針對數據庫執行按需查詢。


select_related對每個查找執行聯接,但將選擇范圍擴展為包括所有聯接表的列。但是,這種方法有一個警告。


聯接有可能使查詢中的行數相乘。當您通過外鍵或一對一字段執行聯接時,行數不會增加。但是,多對多聯接沒有此保證。因此,Django限制select_related了不會意外導致大規模聯接的關系。


對于“ join in python”來說prefetch_related,應該比它還要令人震驚。它為要連接的每個表創建一個單獨的查詢。它使用WHERE IN子句過濾每個表,例如:


SELECT "credential"."id",

       "credential"."uuid",

       "credential"."identity_id"

FROM   "credential"

WHERE  "credential"."identity_id" IN

    (84706, 48746, 871441, 84713, 76492, 84621, 51472);

將每個表拆分為一個單獨的查詢,而不是執行可能包含太多行的單個聯接。


查看完整回答
反對 回復 2019-10-05
?
慕妹3146593

TA貢獻1820條經驗 獲得超9個贊

我會對您關于預取相關的評論“通常沒有多大意義”提出異議。對于標記為唯一的FK字段,這是正確的,但是在多行具有相同FK值(作者,用戶,類別,城市等)的任何地方,預取會減少Django和DB之間的帶寬,但不會重復行。通常,它在數據庫上使用的內存也較少。這些通常比單個額外查詢的開銷更為重要。鑒于這是一個相當普遍的問題的最佳答案,我認為應該在答案中注明。

查看完整回答
反對 回復 2019-10-05
  • 3 回答
  • 0 關注
  • 1780 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號