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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
gedorinku
October 05, 2023
Programming
130
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
N+1 問題の解決と computed_model
gedorinku
October 05, 2023
More Decks by gedorinku
See All by gedorinku
Active Record Encryption と AWS KMS でエンベロープ暗号化
gedorinku
0
750
Wantedly のバックエンドの将来に向けた取り組みと課題 - Wantedly Tech Night 2024/5
gedorinku
0
170
Porting mruby/c for the SNES (Super Famicom) - RubyKaigi 2024
gedorinku
0
5k
部内での競プロ用ジャッジシステム
gedorinku
0
1.8k
部内ジャッジを作る話
gedorinku
1
130
プロラボ年度末報告会 HackDay / Hack U 福岡
gedorinku
0
180
Kotlin入門しました
gedorinku
0
300
Other Decks in Programming
See All in Programming
Family mrubyの進捗
kishima
1
100
Swift愛好会100回記念 第1回を振り返る
jollyjoester
0
120
GraphRAGのKnowledge Graphを 直接!見る/View-GraphRAG's-KnowledgeGraph-directly!
tyumugi1113
0
250
AIと壁打ちしながら進めるコスト管理
fufuhu
2
2k
Webプラットフォームで議論されているセキュリティ課題 / Security issues being discussed on Web Platforms
petamoriken
0
250
新人はどこまで自力でやり、どこからAIに頼るべきか/エンジニア育成に向き合う_先輩たちの悩みと知見共有会
toppan_digital_dev
1
580
フロントエンドUIフレームワークのこれまでとこれから
ssssota
1
790
Laravelのアプリケーションをどこにデプロイするか #ツナギメオフライン.9
akase244
0
120
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
960
LL言語やWebフレームワークのPostgreSQL対応 〜DBの機能がユーザーに届くまで〜
kentaroutakeda
0
140
DynamoDBの基礎を振り返りながらベクトル検索機能を理解する
musan
3
270
XHTMLが残したもの
yosuke_furukawa
PRO
2
450
Featured
See All Featured
WENDY [Excerpt]
tessaabrams
12
39k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
820
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
430
Embracing the Ebb and Flow
colly
88
5.2k
Building Adaptive Systems
keathley
44
3.2k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
290
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Leo the Paperboy
mayatellez
8
2.2k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
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