Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Caching associations in rails
Search
horikawa
August 14, 2019
Technology
1
320
Caching associations in rails
horikawa
August 14, 2019
Tweet
Share
More Decks by horikawa
See All by horikawa
Create Action Mailbox Sample Application
casix
1
340
Rails 4.2→5.2アップデート
casix
0
380
Rails 6.0 Action Mailboxについて
casix
0
370
Other Decks in Technology
See All in Technology
iOSチームとAndroidチームでブランチ運用が違ったので整理してます
sansantech
PRO
0
150
DynamoDB でスロットリングが発生したとき_大盛りver/when_throttling_occurs_in_dynamodb_long
emiki
1
440
オープンソースAIとは何か? --「オープンソースAIの定義 v1.0」詳細解説
shujisado
10
1.3k
OCI 運用監視サービス 概要
oracle4engineer
PRO
0
4.8k
DynamoDB でスロットリングが発生したとき/when_throttling_occurs_in_dynamodb_short
emiki
0
260
10XにおけるData Contractの導入について: Data Contract事例共有会
10xinc
6
670
IBC 2024 動画技術関連レポート / IBC 2024 Report
cyberagentdevelopers
PRO
1
120
AGIについてChatGPTに聞いてみた
blueb
0
130
障害対応指揮の意思決定と情報共有における価値観 / Waroom Meetup #2
arthur1
5
490
Storybook との上手な向き合い方を考える
re_taro
2
300
誰も全体を知らない ~ ロールの垣根を超えて引き上げる開発生産性 / Boosting Development Productivity Across Roles
kakehashi
2
230
Why App Signing Matters for Your Android Apps - Android Bangkok Conference 2024
akexorcist
0
130
Featured
See All Featured
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
900
Visualization
eitanlees
145
15k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
27
4.3k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.3k
Building an army of robots
kneath
302
43k
How to Ace a Technical Interview
jacobian
276
23k
Making the Leap to Tech Lead
cromwellryan
133
8.9k
YesSQL, Process and Tooling at Scale
rocio
169
14k
GraphQLの誤解/rethinking-graphql
sonatard
67
10k
Transcript
AssociationͷΩϟογϡ ӡ༻ʹؾΛ͚ͭͯ (Otemachirb#20) גࣜձࣾπΫϧόɹαʔόαΠυΤϯδχΞ ງɹ@CASIXx1
• ීஈʮcowcamoʯͱ͍͏ΞϓϦΛ։ൃͯ͠ ·͢ • αʔόαΠυɺRailsʢ5.2ʣΛͬͯ·͢
ISUCON͍ۙͰ͢Ͷ
ISUCONͷաڈ ͬͯΔͷͰ͕͢
N + 1 ఆ൪Ͱ͢ΑͶɻɻɻ
෮शʣN + 1ͱʁ
ҎԼͷϞσϧ͕͋ͬͨ߹ app/models/user.rb class User < ApplicationRecord has_many :memos
end app/models/memo.rb class Memo < ApplicationRecord belongs_to :user end
͜ΕΛ࣮ߦ͢Δͱ… @memos = Memo.all @memos.each do |memo| memo.id
memo.user.name end
N + 1͕ൃੜ͢Δ N(memo.userͷ) + 1(Memo.allͷΞΫηε) SELECT 'memos'.* FROM 'memos'
# Memo.allͷΞΫηε # memo.user.nameͷΞΫηε SELECT 'users'.* FROM 'users' WHERE 'users'.'id' = 1 LIMIT 1 SELECT 'users'.* FROM 'users' WHERE 'users'.'id' = 2 LIMIT 1 SELECT 'users'.* FROM 'users' WHERE 'users'.'id' = 3 LIMIT 1
RailsͬͯΔͱɺ N + 1Λ؆୯ʹղফͰ͖·͢ΑͶ
includes, preload, eager_load Λ͑ྑ͍ @memos = Memo.all.includes(:user) @memos.each
do |memo| memo.id memo.user.name end SELECT 'memo'.* FROM 'memos' SELECT 'users'.* FROM 'users' WHERE 'users'.'id' IN (1, 2, 3) N + 1→1 + 1ʹͳΔ
includesͱ͔eager_loadͱ͔ ৭ʑ͋Γ·͢ΑͶ
N + 1ΛղܾͰ͖Δ͔൱͔ • N + 1ΛղܾͰ͖ͳ͍ • joins •
N + 1ΛղܾͰ͖Δʢؔ࿈ςʔϒϧใΛؚΊͯΩϟογϡ͢Δʣ • eager_load • LEFT OUTER JOINΛར༻͢Δʢt0_r0Έ͍ͨͳͭʣ • preload • IN۟Λར༻ͯ͠ɺෳΫΤϦͰऔͬͯ͘Δ • whereͰؔ࿈ςʔϒϧͷใΛߜΕͳ͍ • includes • eager_load, preloadΛঢ়گʹԠͯ͡ɺ͍͚͢Δ
AssociationͷΩϟογϡ ສೳ͔??
ύϑΥʔϚϯεతʹ ؾΛ͚ͭͳ͚ΕͳΒͳ͍͋ΔΒ͍͕͠…
ӡ༻໘ͰؾΛ͚ͭͳ͍ͱ͍͚ͳ͍ʂ
ؔ࿈ઌςʔϒϧͷΧϥϜΛ আ͍ͨ͠ͱ͢Δ • UserςʔϒϧͰɺআ͍ͨ͠ΧϥϜ͕͋Δͱ͢Δ • Ծʹɺ deprecated_columnͱ͍͏໊લʹ͠·͢ • Α͠ʂΧϥϜআ͢Δ ϚΠάϨʔγϣϯΛ͔͚Α͏ʂ
• ͔͠͠ɺΤϥʔ͕ग़ͯ͠·͍·ͨ͠ɻ ԿނͰ͠ΐ͏ʁʁ
ؔ࿈ઌςʔϒϧͷΧϥϜΛআ ͍ͨ͠ͱ͢Δ • લఏ݅ • ↓ͷίʔυ͕ଘࡏ͢Δ • ΞϓϦέʔγϣϯίʔυ͔Βɺ deprecated_columnΛࢀর͠ͳ͍Α͏ʹमਖ਼ࡁΈ
@memos = Memo.includes(:user).where(users: { name: ‘horikawa’ }) @memos.each do |memo| memo.id memo.user.name end
͑ • ؔ࿈ςʔϒϧͷΩϟογϡΛऔಘ͢Δࡍʹɺ શͯͷΧϥϜใΛSELECTจͰࢦఆͨ͠ΫΤϦΛൃߦ͠Α͏ͱ͢Δ (SELECT … `users`.`id` AS t1_r0, `users`.`deprecated_column`
AS t1_r1) ↓ • ϚΠάϨʔγϣϯͰɺΧϥϜΛআ͢Δ ˣ • ΫΤϦΛ࣮ߦ͢ΔࡍʹɺΩϟογϡΛ͏ͷͰɺ ଘࡏ͠ͳ͍ΧϥϜʹର͢ΔΞΫηεΛͯ͠ɺΤϥʔ͕ग़Δ
͑ # whereͰ݅ذ͢Δͱɺleft outer joinͰΩϟογϡΛੜ͢Δ @memos = Memo.includes(:user).where(users:
{ name: ‘horikawa’ }) # ॲཧ͕͜͜Βลʹ͍ΔλΠϛϯάͰɺΧϥϜΛআ͞Εͯ͠·͏ͱ… # memo.deprecated_column͕ͳ͍ͱΤϥʔ͕ग़Δ @memos.each do |memo| memo.id memo.user.name end
ରࡦ
Rails 5.xͰ͋Ε • ignored_columnsΛ͓͏ʂ • εΩʔϚใʹՃ͑ͳ͍Α͏ʹͯ͘͠ΕΔ • User.column_namesͰ deprecated_column͕ग़ͳ͚Ε͓k
class User < ApplicationRecord self.ignored_columns = %w(deprecated_column) end
ਖ਼͍͠σϓϩΠॱ • deprecated_columnΛࢀর͢ΔίʔυΛআ͢ Δ ˣ • ignored_columnʹdeprecated_columnΛՃ ˣ • ΧϥϜΛআ
ͪͳΈʹRails 4.xͰ͋Ε • ActiveRecord::Base.columnsΛΦʔόʔϥΠ υͯ͠ɺ deprecated_columnΛreject͢Δඞཁ͕͋Δ Έ͍ͨͰ͢
Rails ্͛Α͏
ࢀߟ • https://moneyforward.com/engineers_blog/2019/04/02/ activerecord-includes-preload-eagerload/ • https://dev.classmethod.jp/server-side/activerecord-join/ • https://qiita.com/ykamez/items/0c81a33ec1b90219d541 • https://qiita.com/SoarTec-lab/items/
a192d381323cb741538e • https://eagletmt.hateblo.jp/entry/2017/09/24/004709