話說剛從 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 是會比較好,至少我是這樣解決的。
發佈留言