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
79
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
430
Wantedly のバックエンドの将来に向けた取り組みと課題 - Wantedly Tech Night 2024/5
gedorinku
0
110
Porting mruby/c for the SNES (Super Famicom) - RubyKaigi 2024
gedorinku
0
4.3k
部内での競プロ用ジャッジシステム
gedorinku
0
1.7k
部内ジャッジを作る話
gedorinku
1
99
プロラボ年度末報告会 HackDay / Hack U 福岡
gedorinku
0
170
Kotlin入門しました
gedorinku
0
270
Other Decks in Programming
See All in Programming
Go製CLIツールをnpmで配布するには
syumai
0
740
The Evolution of Enterprise Java with Jakarta EE 11 and Beyond
ivargrimstad
0
530
CLI ツールを Go ライブラリ として再実装する理由 / Why reimplement a CLI tool as a Go library
ktr_0731
3
630
「次に何を学べばいいか分からない」あなたへ──若手エンジニアのための学習地図
panda_program
3
660
[Codecon - 2025] Como não odiar seus testes
camilacampos
0
100
DMMを支える決済基盤の技術的負債にどう立ち向かうか / Addressing Technical Debt in Payment Infrastructure
yoshiyoshifujii
4
640
What's new in Adaptive Android development
fornewid
0
120
Claude Code で Astro blog を Pages から Workers へ移行してみた
codehex
0
160
Understanding Kotlin Multiplatform
l2hyunwoo
0
230
React 使いじゃなくても知っておきたい教養としての React
oukayuka
11
1.3k
ZeroETLで始めるDynamoDBとS3の連携
afooooil
0
130
PHPUnitの限界をPlaywrightで補完するテストアプローチ
yuzneri
0
340
Featured
See All Featured
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.9k
Optimizing for Happiness
mojombo
379
70k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
Building Adaptive Systems
keathley
43
2.7k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.6k
Practical Orchestrator
shlominoach
189
11k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
21k
Six Lessons from altMBA
skipperchong
28
3.9k
Mobile First: as difficult as doing things right
swwweet
223
9.7k
Speed Design
sergeychernyshev
32
1k
Into the Great Unknown - MozCon
thekraken
40
1.9k
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