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來拼接多個條件,然後編寫分頁外掛程式...