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
N+1 問題の解決と computed_model
Search
gedorinku
October 05, 2023
Programming
0
63
N+1 問題の解決と computed_model
gedorinku
October 05, 2023
Tweet
Share
More Decks by gedorinku
See All by gedorinku
Active Record Encryption と AWS KMS でエンベロープ暗号化
gedorinku
0
320
Wantedly のバックエンドの将来に向けた取り組みと課題 - Wantedly Tech Night 2024/5
gedorinku
0
95
Porting mruby/c for the SNES (Super Famicom) - RubyKaigi 2024
gedorinku
0
4.1k
部内での競プロ用ジャッジシステム
gedorinku
0
1.6k
部内ジャッジを作る話
gedorinku
1
97
プロラボ年度末報告会 HackDay / Hack U 福岡
gedorinku
0
160
Kotlin入門しました
gedorinku
0
270
Other Decks in Programming
See All in Programming
Optimizing JRuby 10
headius
0
500
新しいPHP拡張モジュールインストール方法「PHP Installer for Extensions (PIE)」を使ってみよう!
cocoeyes02
0
420
Instrumentsを使用した アプリのパフォーマンス向上方法
hinakko
0
130
2ヶ月で生産性2倍、お買い物アプリ「カウシェ」4チーム同時改善の取り組み
ike002jp
1
100
Unlock the Potential of Swift Code Generation
rockname
0
270
Laravel × Clean Architecture
bumptakayuki
PRO
0
110
Dissecting and Reconstructing Ruby Syntactic Structures
ydah
2
1.3k
一緒に働きたくなるプログラマの思想 #QiitaConference
mu_zaru
75
18k
Java 24まとめ / Java 24 summary
kishida
3
510
PHP で学ぶ OAuth 入門
azuki
1
210
Cursorを活用したAIプログラミングについて 入門
rect
0
100
Cursor/Devin全社導入の理想と現実
saitoryc
25
18k
Featured
See All Featured
Product Roadmaps are Hard
iamctodd
PRO
52
11k
Music & Morning Musume
bryan
47
6.5k
Side Projects
sachag
453
42k
A better future with KSS
kneath
239
17k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
32
5.4k
A designer walks into a library…
pauljervisheath
205
24k
The Pragmatic Product Professional
lauravandoore
33
6.6k
Adopting Sorbet at Scale
ufuk
76
9.3k
Building Adaptive Systems
keathley
41
2.5k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.6k
Six Lessons from altMBA
skipperchong
28
3.7k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
34
2.2k
Transcript
© 2023 Wantedly, Inc. N+1 問題の解決と computed_model Oct. 5 2023
- Ryota Egusa (@gedorinku)
Wantedly のアーキテクチャ © 2023 Wantedly, Inc. Rails のマイクロサービス GraphQL のデータソースなどに使われる、汎用
的な API を持つ
加工した値を返すモデルのメソッド class User < ApplicationRecord has_many :work_experiences # => "ウォンテッドリー株式会社
/ エンジニア" def position_description work_experience = work_experiences.max_by { _1.started_at } "#{work_experience.company_name} / #{work_experience.position}" end end © 2023 Wantedly, Inc.
Preload と N+1 問題 class User < ApplicationRecord has_many :work_experiences
… end User.where(...).map(&:position_description) User.preload(:work_experiences).where(...).map(&:position_description) © 2023 Wantedly, Inc.
computed_model による解決方法 class User define_primary_loader :raw_user do ... end define_loader
:work_experiences do ... end dependency :work_experiences computed def position_description work_experience = work_experiences.max_by { _1.started_at } "#{work_experience.company_name} / #{work_experience.position}" end end © 2023 Wantedly, Inc. 依存関係をここに書く ここに書かれていないものを使うと エラーになる
Active Record をデータソースとして使う例 class User define_primary_loader :raw_user do |_, ids:,
**| RawUser.where(id: ids).map do |raw_user| User.new(raw_user) end end define_loader :work_experiences do ... end end © 2023 Wantedly, Inc.
他サービスの API をデータソースとして使う例 class User define_primary_loader :raw_user do ... end
define_loader :work_experiences, key: -> { id } do |user_ids, _, **| WorkExperienceApiClient.list(user_ids: user_ids).group_by(&:user_id) end end © 2023 Wantedly, Inc.
computed_model からデータを読む 指定していないフィールドを使うとエラーになる users = User.batch_get(user_ids, [:position_description]) users.map(&:position_description) users.map(&:name) #
=> error © 2023 Wantedly, Inc.
まとめ 1. 抽象化を損なわず依存関係解決 ◦ N+1問題を防ぎ、必要なデータだけ読み込む 2. データソースには Active Record に限らず
HTTP API なども使える © 2023 Wantedly, Inc. https://github.com/wantedly/computed_model