Rails N+1問題 with joins, includes, preload and eager_load
資料庫的操作是影響網站效能的重要因素,而在存取資料時幾乎一定會遇到 N+1 問題。本篇文章將簡要探討 includes 的使用時機,以及與其相似的 preload 和 eager_load 方法。此外,我們還會介紹在處理多表格操作時常用的 joins。 1. 造成 N+1 問題的原因 我們先想像一個情境,你正在開發商家的訂單系統,其中有兩個 Model,分別是Customer與Order,Customer記載顧客資料,並且每個顧客擁有多筆訂單Order # customer.rb class Customer < ApplicationRecord has_many :orders end # order.rb class Order < ApplicationRecord belongs_to :customer end 現在我們想要呈現4位顧客的個人資訊以及他們各自的所有訂單,你可能會這樣寫: Customer.limit(4).each{|customer| puts customer.orders} Rails ORM 產生的 SQL 指令如下: SELECT 'customers'.* FROM 'customers' LIMIT 4 SELECT 'orders'.* FROM 'orders' WHERE 'orders'.'customer_id'=1 SELECT 'orders'.* FROM 'orders' WHERE 'orders'.'customer_id'=2 SELECT 'orders'.* FROM 'orders' WHERE 'orders'.'customer_id'=3 SELECT 'orders'.* FROM 'orders' WHERE 'orders'....