David Chao

David Chao

#
php 筆記 程式設計

Laravel Relation 的一些坑

2019/06/28

話說剛從 Codeigniter 轉到 Laravel 的時候,Eloquent ORM 實在是讓人驚艷啊!

尤其是 Relation 的部份,讓程式更簡潔、效能又好,

在 CI 的時候通常都是千奇百怪的 Join 來達到目的,

But!有一些情境 Relation 不是那麼適合,以下列出幾個最近採到的坑吧。

1. one to many 的條件篩選

我們用客戶跟客戶訂單來舉例好了,假設你要列出客戶並 With 最後一筆消費紀錄

Model 的 Relation 像這樣

 

這樣我們可以很輕鬆地取值

 

但是假設你要對最後一筆訂單做條件搜尋的時候,就會出問題了,

假設你想找最後定安是買 A 產品 或是 超過 1000 元 之類的條件,簡單來說就是對最後一筆來做篩選,可能會這樣寫:

 

你會發現實際上的結果會是,先找符合 where 條件的訂單,再回傳最後一筆出來。

 

2. 用 Relation 做排序

同樣是客戶與訂單的例子,假設要列出客戶用消費金額的加總做排序,因為 With 適用 Exist 做連結,所以不能直接用  Order 來做排序,必須先把結果 Get 出來後用 Collection 的 SortBy 來處理:

 

看起來也不會怎樣,是沒錯,但會產生幾個問題

分頁問題

這樣的寫法就沒辦用 Sql 做 Paginate,必須先把資料全部拿出來再做分頁。

效能問題

Paginate 本來是用 sql 的 limit 跟 offset 來做分頁,所以資料量會限制在一定的大小,通常也可以吃到 index 就不用掃全表,但現在只能全拿,所以效能差很多。

用 sortByDesc 跑 15 萬筆的客戶紀錄加上約 50 萬筆的訂單紀錄,要 1 分多鐘,臉都綠了,所以這樣的情境呢,用 LeftJoin 是會比較好,至少我是這樣解決的。

趙大衛
貫徹死了都要創業為信念,卻差一點讓口號變成事實! 目前正在進行第一次修養,請多多支持。

發佈留言