摘要:下面將通過一些例子,進(jìn)一步幫助您了解如何優(yōu)化查詢。時(shí)發(fā)生次查詢,加上先前一次查詢,累計(jì)產(chǎn)生次查詢。預(yù)加載接下來,如果我們打算使用關(guān)聯(lián)的模型數(shù)據(jù),我們可以使用預(yù)加載將該個(gè)查詢總數(shù)減少到個(gè)查詢。
原文譯自eloquent-eager-loading,簡(jiǎn)化其前面構(gòu)造數(shù)據(jù)部分。
對(duì)象關(guān)系映射(ORM)使數(shù)據(jù)庫的工作變得非常簡(jiǎn)單。 在以面向?qū)ο蟮姆绞蕉x數(shù)據(jù)庫關(guān)系時(shí),可以輕松查詢相關(guān)的模型數(shù)據(jù),開發(fā)人員可能不會(huì)注意底層數(shù)據(jù)庫調(diào)用。
下面將通過一些例子,進(jìn)一步幫助您了解如何優(yōu)化查詢。
假設(shè)您從數(shù)據(jù)庫收到了100個(gè)對(duì)象,并且每個(gè)記錄都有1個(gè)關(guān)聯(lián)模型(即belongsTo)。 默認(rèn)使用ORM將產(chǎn)生101個(gè)查詢; 如下所示:
//獲取已發(fā)布的100條文章 $posts = Post::limit(100)->get(); //一次查詢 $authors = array_map(function($post) { // 對(duì)作者模型生成查詢 return $post->author->name; }, $posts);
我們?cè)诓樵儠r(shí)沒有告訴Post模型,我們還需要所有的作者,所以每次從單個(gè)Post模型實(shí)例獲取作者的名字時(shí),都會(huì)發(fā)生多帶帶的查詢。
預(yù)加載array_maps時(shí)發(fā)生100次查詢,加上先前一次查詢,累計(jì)產(chǎn)生101次查詢。
接下來,如果我們打算使用關(guān)聯(lián)的模型數(shù)據(jù),我們可以使用預(yù)加載將該101個(gè)查詢總數(shù)減少到2個(gè)查詢。 只需要告訴模型你需要什么來加載。如下:
//獲取已發(fā)布的100條文章 - 并預(yù)加載文章對(duì)應(yīng)作者 $posts = Post::with("author")->limit(100)->get();//2次查詢 $authors = array_map(function($post) { // 對(duì)作者模型生成查詢 return $post->author->name;//這里講不在產(chǎn)生查詢 }, $posts);
如果你開啟了sql日志,你將看到上述預(yù)加載將只會(huì)產(chǎn)生兩條查詢:
select * from `posts` select * from `authors` where `authors`.`id` in (?, ?, ?, ?, ?) [1,2,3,4,5]
如果您有多個(gè)關(guān)聯(lián)模型,則可以使用數(shù)組加載它們:
$posts = AppPost::with(["author", "comments"])->get();
接下來我們重新定義如下關(guān)系
Post -> belongsTo -> Author //每個(gè)文章只屬于一個(gè)用戶 Author -> hasMany -> Post //每個(gè)用戶擁有多個(gè)文章 Author -> hasOne -> Profile //每個(gè)用戶只有一個(gè)簡(jiǎn)介
考慮下述情況:獲取已發(fā)布文章所屬作者的個(gè)人簡(jiǎn)介。
//獲取所有文章 - 并預(yù)加載文章對(duì)應(yīng)作者 $posts = AppPost::with("author")->get();//兩次查詢 //根據(jù)每個(gè) `作者` 獲取其簡(jiǎn)介 $posts->map(function ($post) { //雖然我們直接通過$author = $post->author不會(huì)產(chǎn)生查詢, //但當(dāng)調(diào)用$author->profile時(shí),每次都會(huì)產(chǎn)生一個(gè)新查詢 return $post->author->profile; });
假設(shè)上述AppPost::with("author")->get()有100條記錄,將會(huì)產(chǎn)生多少條查詢呢?
通過優(yōu)化預(yù)加載,我們可以避免嵌套關(guān)系中的額外查詢。
//獲取所有文章 - 并預(yù)加載文章對(duì)應(yīng)作者及每個(gè)作者對(duì)應(yīng)de profile $posts = AppPost::with("author.profile")->get();//三次查詢 $posts->map(function ($post) { //不在產(chǎn)生新查詢 return $post->author->profile; });
你可以打開你的sql日志看到對(duì)應(yīng)的三條查詢。
select * from `posts` select * from `authors` where `authors`.`id` in (?, ?, ?, ?, ?) [.....] select * from `profiles` where `profiles`.`author_id` in (?, ?, ?, ?, ?) [.....]懶惰加載
有時(shí)候您可能只需要根據(jù)條件收集相關(guān)聯(lián)的模型。 在這種情況下,您可以懶惰地調(diào)用相關(guān)數(shù)據(jù)的其他查詢:
$posts = AppPost::all();//一次查詢 $posts->load("author.profile");//兩次查詢 $posts->map(function ($post) { //不在產(chǎn)生新查詢 return $post->author->profile; });
查看您的sql日志,總共看到三個(gè)查詢,但只有調(diào)用$posts->load()時(shí)才會(huì)顯示。
結(jié)論希望您更加了解有關(guān)加載型號(hào)的更多信息,并了解其在更深層次上的工作原理。 Laravel相關(guān)的文檔已經(jīng)很全面了,希望額外的實(shí)踐練習(xí)可以幫助您更有信心優(yōu)化關(guān)系查詢。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/25584.html
摘要:為關(guān)聯(lián)關(guān)系設(shè)置約束子模型的等于父模型的上面設(shè)置的字段的值子類實(shí)現(xiàn)這個(gè)抽象方法通過上面代碼看到創(chuàng)建實(shí)例時(shí)主要是做了一些配置相關(guān)的操作,設(shè)置了子模型父模型兩個(gè)模型的關(guān)聯(lián)字段和關(guān)聯(lián)的約束。不過當(dāng)查詢父模型時(shí),可以預(yù)加載關(guān)聯(lián)數(shù)據(jù)。 Database 模型關(guān)聯(lián) 上篇文章我們主要講了Eloquent Model關(guān)于基礎(chǔ)的CRUD方法的實(shí)現(xiàn),Eloquent Model中除了基礎(chǔ)的CRUD外還有一個(gè)...
摘要:但也因?yàn)閼?yīng)有盡有使得框架的性能比其他高性能框架低了些,為此給了幾個(gè)解決方案路由緩存經(jīng)有關(guān)部門研究,路由緩存可有效加快訪問速度以上。有朋友說框架最重要的東西是路由,我倒認(rèn)為最重要的是框架中異于其他框架且能解決痛點(diǎn)的東西,如的。 showImg(https://segmentfault.com/img/remote/1460000006767764); 在程序界的遠(yuǎn)古時(shí)期,大神們手持鍵盤敲...
摘要:在本文中,我們將了解中的懶加載和即時(shí)加載以及它如何在后臺(tái)運(yùn)行?,F(xiàn)在所有的房屋數(shù)據(jù)和在關(guān)系表中的數(shù)據(jù)都同時(shí)加載出來了,查詢的語句的是使用即時(shí)加載時(shí)僅執(zhí)行個(gè)查詢。總結(jié)現(xiàn)在你理解了這個(gè)過程,希望它能幫助你理解懶加載和即時(shí)加載的用法和基本原理。 Laravel中的Eloquent(ORM)的工作方式很令人驚訝,并提供訪問數(shù)據(jù)庫的非常簡(jiǎn)單的方法。在本文中,我們將了解Laravel Eloquen...
摘要:本文翻譯整理至介紹你可以可以使用的在線工具輕松的將原生和歷史遺留語句轉(zhuǎn)換為函數(shù)式語句。使用點(diǎn)擊此處可試用此工具你只需輸入您的語句,此工具便會(huì)返回一個(gè)函數(shù)式語句。而則會(huì)將嘗試將反引號(hào)中的內(nèi)容作為命令來執(zhí)行,詳見執(zhí)行運(yùn)算符。 showImg(https://segmentfault.com/img/remote/1460000012292770?w=2200&h=1125); 本文翻譯整理...
摘要:通過自定義的查詢加載和大多數(shù)情況下,你需要按層級(jí)排序祖先集合可以被預(yù)加載視圖模板中面包屑將祖先的全部取出后轉(zhuǎn)換為數(shù)組,在用拼接為字符串輸出。 原文鏈接:http://www.pilishen.com/posts...; 歡迎作客我們的php&Laravel學(xué)習(xí)群:109256050 laravel-nestedset是一個(gè)關(guān)系型數(shù)據(jù)庫遍歷樹的larvel4-5的插件包 目錄: Nes...
閱讀 1693·2021-10-27 14:13
閱讀 1966·2021-10-11 10:59
閱讀 3449·2021-09-24 10:26
閱讀 1985·2019-08-30 12:48
閱讀 3108·2019-08-30 12:46
閱讀 2093·2019-08-30 11:16
閱讀 1486·2019-08-30 10:48
閱讀 2858·2019-08-29 16:54