[英]Laravel 5: Does Eloquent eager load by default?
我有這個結構:
學校-> hasMany->班級
所以當我通過artisan tinker
嘗試以下代碼時
App\School::with('schoolclasses')->find(2283)->schoolclasses;
我可以順利上課。
但是當我嘗試不使用with時,我仍然會得到相同的結果而不會出現問題:
App\School::find(2283)->schoolclasses;
Eloquent
默認加載Eloquent
嗎? 如果是這樣,如何禁用它?
不,Laravel默認不急於加載。 讓我們逐步進行此操作。 讓我們忽略->schoolclasses;
一會兒。
App\School::with('schoolclasses')->find(2283);
這將查詢數據庫兩次。 首先,它將獲得主鍵2283的School
。然后,它將立即查詢數據庫並獲取所有相關的schoolclasses
。
App\School::find(2283);
這將只查詢數據庫一次。 它只會得到School
。 到目前為止,尚未完成任何急切的加載。 如果調試並跟蹤數據庫查詢,您將看到它只會查詢數據庫一次,而急於加載的數據庫將查詢兩次。
當您嘗試訪問schoolclasses
做->schoolclasses;
,一切實際上都有效。 那為什么得到相同的結果呢? 這有點騙人,但是不一樣。 當您嘗試訪問schoolclasses
,Laravel將檢查它是否已經被加載。 如果是這樣,它將返回schoolclasses
的集合。 沒有查詢完成。 它只是立即返回它們。 但是,如果您不急於加載它們,Laravel將立即查詢數據庫並獲取schoolclasses
。 最終,對於此特定示例,您將獲得相同的結果,但是查詢數據庫時卻有所不同。
但是,這實際上是渴望加載的主要好處的不良示例。
渴望加載的主要好處是減輕了N + 1查詢問題。 假設您想獲得5所學校及其所有班級。 如果不急於加載,這是您要執行的操作:
$schools = School::take(5)->get();
foreach ($schools as $school)
{
$schoolclasses = $school->schoolclasses;
}
對於這樣一個簡單的任務,總共有6個查詢。 我在下面添加了注釋,以了解查詢來自何處:
$schools = School::take(5)->get(); // First query
foreach ($schools as $school)
{
// For each school, you are querying the database again to get its related classes.
// 5 schools = 5 more queries
$schoolclasses = $school->schoolclasses;
}
但是,如果您渴望加載所有內容,則只有兩個查詢:
// Two queries here that fetches everything
$schools = School::with('schoolclasses')->take(5)->get();
foreach ($schools as $school)
{
// No more queries are done to get the classes because
// they have already been eager loaded
$schoolclasses = $school->schoolclasses;
}
您兩次寫相同。 第一個請求到達學校,其課程如下:
學校:
班級班級
然后,您僅獲得課程。
第二個直接獲取這些類。 結果是相同的,因為您要的是相同的記錄。
如果您不想獲得急切加載的結果,那就不要查詢它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.