Rails中如何避免N 1問題

2021-12-30 12:05:44 字數 1305 閱讀 1275

n+1問題

n+1問題是資料庫訪問中最常見的乙個效能問題,首先介紹一下什麼是n+1問題:

舉個例子,我們資料庫中有兩張表,乙個是customers,乙個是orders。orders中含有乙個外來鍵customer_id,指向了customers的主鍵id。

想要得到所有customer以及其分別對應的order,一種寫法是

select * from customers;

對於每乙個customer;

select * from orders where orders.customer_id = #

這樣我們實際對資料庫做了n+1次查詢:選擇所有customer一次得到n個customer,對於n個customer分別選擇其對應的order一共n次。所以,一共執行了n+1次查詢,這就是n+1問題

n+1問題的一般解決方法

使用left join一次性取出所有資料:

select * from customers left join orders on customers.id = orders.customer_id

這樣雖然取出的資料相對多一些,但是只需要一次執行

rails中的n+1問題

因為rails使用activerecord訪問資料庫。所以,它的n+1問題暴露的不是那麼明顯。

假設我們有兩個activerecord:customer、order。

customer has_many :orders

order belong_to :customer

一般我們獲取所有customer的方法是:

customers = customer.all

如果我們後面緊跟著

customers.each

這樣就會產生n+1問題,因為在獲取所有customer的時候,是沒有去取orders的。然後在後面each遍歷的時候,就會挨個的取orders,這就構成了rails中的n+1

問題。rails中的n+1問題解決方法

customers = customers.includes(:orders)

這樣就在讀取customers的時候也一次性的把orders都取出了。後面的參考資料有更詳細的說明

更多

並不是對於所有的涉及到外來鍵關聯,一對多的問題都會產生n+1問題,這還是要取決於你的業務。比如你的方法在執行時,只有很少的可能會去獲取customer對應的orders,那就保持預設的lazy方式去就行了。強制eager去取反而得不償失。

Rails中如何避免N 1問題

n 1問題 n 1問題是資料庫訪問中最常見的乙個效能問題,首先介紹一下什麼是n 1問題 舉個例子,我們資料庫中有兩張表,乙個是customers,乙個是orders。orders中含有乙個外來鍵customer id,指向了customers的主鍵id。想要得到所有customer以及其分別對應的o...

hibernate中的n 1問題

前提 hibernate預設表與表的關聯方法是fetch select 不是fetch join 這都是為了懶載入而準備的。1 一對多 在1的這方,通過1條sql查詢得到了1個物件,由於關聯的存在 那麼又需要將這個物件關聯的集合取出,所以合集數量是n還要發出n條sql,於是本來的1條sql查詢變成了...

如何解決查詢N 1問題

1.使用資料庫left join來實現,在一次資料庫查詢中查出多條資料,但是要對結果進行分組組裝。但是對於分頁支援不好,需要自定義分頁外掛程式,現有解決思路如下 編寫sql時,將主表的條件寫入到where條件中,將所有left join的條件寫到on中,使用and來拼接多個條件,然後編寫分頁外掛程式...