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
54
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
49
Wantedly のバックエンドの将来に向けた取り組みと課題 - Wantedly Tech Night 2024/5
gedorinku
0
77
Porting mruby/c for the SNES (Super Famicom) - RubyKaigi 2024
gedorinku
0
3.8k
部内での競プロ用ジャッジシステム
gedorinku
0
1.6k
部内ジャッジを作る話
gedorinku
1
89
プロラボ年度末報告会 HackDay / Hack U 福岡
gedorinku
0
150
Kotlin入門しました
gedorinku
0
260
Other Decks in Programming
See All in Programming
Pythonでもちょっとリッチな見た目のアプリを設計してみる
ueponx
1
480
“あなた” の開発を支援する AI エージェント Bedrock Engineer / introducing-bedrock-engineer
gawa
11
1.8k
Honoをフロントエンドで使う 3つのやり方
yusukebe
4
2.1k
Honoとフロントエンドの 型安全性について
yodaka
4
250
バックエンドのためのアプリ内課金入門 (サブスク編)
qnighy
8
1.7k
第3回関東Kaggler会_AtCoderはKaggleの役に立つ
chettub
3
890
Amazon S3 TablesとAmazon S3 Metadataを触ってみた / 20250201-jawsug-tochigi-s3tables-s3metadata
kasacchiful
0
100
Domain-Driven Transformation
hschwentner
2
1.9k
XStateを用いた堅牢なReact Components設計~複雑なClient Stateをシンプルに~ @React Tokyo ミートアップ #2
kfurusho
1
770
Pulsar2 を雰囲気で使ってみよう
anoken
0
230
Immutable ActiveRecord
megane42
0
130
Multi Step Form, Decentralized Autonomous Organization
pumpkiinbell
1
660
Featured
See All Featured
Adopting Sorbet at Scale
ufuk
74
9.2k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.5k
Build The Right Thing And Hit Your Dates
maggiecrowley
34
2.5k
The Power of CSS Pseudo Elements
geoffreycrofte
75
5.5k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.8k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
27
1.9k
Become a Pro
speakerdeck
PRO
26
5.1k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
Faster Mobile Websites
deanohume
306
31k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.7k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
29
1k
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