rails 當中有很多方便可以做資料查詢的功能,可以好好研究一下。
Model
1 2 3 4 5 6 7 8 9 10 11 12 | |
includes
includes主要用於可以直接將相關連的資料,在同一筆查詢,一起撈出來- 跟 preload 類似,加上
reference則和eager_load類似 - 會有兩條以上的 query,以下是
Blog Load&Post Load
1 2 3 4 5 6 7 | |
可以看到後面有 IN (1, 2, 3),就是將上面一筆一筆查詢,變成這種方式一次撈出來。這樣在 view 中執行 user.posts 就不會再去資料庫查詢,因為已經都先撈出來了。
1 2 3 4 5 6 7 8 | |
透過關聯 table 做搜尋
記得 where 後面的 posts 是 table_name
用 includes 就沒問題,不過這就是 eager_load,以下就會使用 LEFT OUTER JOIN
1 2 3 4 5 6 | |
改用 SQL 寫法,如果用 SQL 寫法就必須搭配上 references,否則會找不到
這邊的 posts.title 也是 table name
1 2 3 | |
preload
- 跟 includes 類似,主要差別在於無法用 where 條件去查關聯到的 table 欄位
- 會有兩條以上的 query,以下是
Blog Load&Post Load
1 2 3 4 | |
無法透過關聯的欄位做搜尋
- perload 只負責載入物件和關聯物件, 並沒有聯結關聯物件
- 就是只知道 Blog table
後面關聯的名稱,必須是 table 名稱,Blog.preload(:posts).where(
table 名稱: { title:“Post 1-1” } )
1 2 3 4 5 6 7 | |
ActiveRecord::Associations::Preloader
we can preload our data whenever we want.
1 2 | |
希望能將 query 分開
這邊如果將 preload 改成 includes 則會變成一個 outer join 的 query
底下是希望能取得 blog 底下 post id 是 1, 2, 3 的 blog,但是一樣要取出該 blog 所有的 posts
1
| |
eager_loading
- One query
LEFT OUTER JOINedin any query rather than loaded separately. - 相當於
includes+references也就是指明的條件是關聯物件中的字段時, Rails 會生成LEFT OUTER JOIN語句. - Eager loading 是載入由 Model.find 回傳的物件關聯記錄的機制,將查詢數降到最低。
- Active Record 透過使用 Model.find 搭配 includes 方法,可預先指定所有會載入的關聯。有了 includes,Active Record 確保所有指定的關聯,加載的查詢減到最少。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
references
- 只有在 includes 可以使用,主要是讓 includes 像 eager_load
- where 的這種用法只對參數是 Hash 有效,傳入的參數若是 SQL,則需加上要使用 references 來強制連接資料表
1 2 3 | |
joins (inner join)
joins 則是關聯其他資料庫,並整合成一個大表,因此如果透過 association 去取資料的時候,依樣會有 n+1 query(但因為已經是一個大表,所以資訊也可以透過大表取得,不需要再去拉 association)
1 2 3 4 5 | |
回傳的是所有有 post 的 blog,但並不會將 post 資料撈出來,只是去做比對,因此再用 blog.posts.each { |post| post.id } ,一樣會去資料庫中撈出資料。
joins 範例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
joins 和 include 的區別
- include 主要是關聯的 table 透過
IN()取得,放在記憶體,後續查詢時,就不會再去查 - joins 則是將兩張表合成一張(必須id有對到),再透過欄位去做塞選
- joins 為
inner join, include 為left outer join
1 2 3 4 5 6 7 8 | |

Other
use sql in rails
1
| |
官方資料:
參考資料:
- 網站效能
- ActiveRecord - 資料表關聯
- preload, eager_load, includes, references, and joins in Rails
- Preload, Eagerload, Includes and Joins
- Making sense of ActiveRecord joins, includes, preload, and eager_load
- Making sense of ActiveRecord joins, includes, preload, and eager_load
- Mysql: 圖解 inner join、left join、right join、full outer join、union、union all的區別
- Rails 3 種做到 eager loading 方法
- Rails includes and joins
- 3 ways to do eager loading (preloading) in Rails 3 & 4