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
GraphQL データ取得高速化
Search
ham
July 06, 2023
0
430
GraphQL データ取得高速化
tsukiji.graphql #1での発表資料です。
https://tsukiji-graphql.connpass.com/event/281413/
ham
July 06, 2023
Tweet
Share
More Decks by ham
See All by ham
生成AI活用でエンジニア組織はどう変わったのか?
ham0215
1
64
メンバーがオーナーシップを発揮しやすいチームづくり
ham0215
2
420
Platform Engineeringのエッセンスを小規模な開発組織に取り入れた事例紹介
ham0215
9
1.7k
開発者の定量・定性データを組み合わせて開発者体験を把握するための取り組み
ham0215
5
2.1k
アジャイルを始めるための基礎を固める
ham0215
1
98
開発者体験を意識した開発チームの生産性向上の取り組み
ham0215
3
950
MySQLのViewを活用した安全なマルチテナントの実現方法
ham0215
2
1.2k
開発パフォーマンスを最大化するための開発体制
ham0215
7
1.8k
今こそ思い出すGraphQLの特徴
ham0215
0
190
Featured
See All Featured
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
120k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.3k
Visualization
eitanlees
146
15k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
7k
Optimizing for Happiness
mojombo
376
70k
Code Reviewing Like a Champion
maltzj
521
39k
Making Projects Easy
brettharned
116
6k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
GraphQLの誤解/rethinking-graphql
sonatard
68
10k
[RailsConf 2023] Rails as a piece of cake
palkan
53
5.2k
The Cult of Friendly URLs
andyhume
78
6.2k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
4
410
Transcript
GraphQL データ取得高速化 tsukiji.graphql #1 2023/07/06 ham
自己紹介 【略歴】 新卒でSIerとして就職 その後、Web系企業やスタートアップを経てファインディに参画 ファインディではFindy Team+のフロント&バックエンド開発を担当 React+Rails+GraphQL+AWSを使って開発しています 浜田 直人 (ham)
ファインディ株式会社 @hamchance0215
N+1問題
users { id profile { name } } N+1問題 –
userを複数返却するQuery – id fieldはusersテーブルから取得 – profileはprofilesテーブルから取得 # Ruby code def resolve User.all end
users { id profile { name } } N+1問題 –
usersは10件Hit select * from users; – profilesを1件ずつ取得 => N+1問題 select * from profiles where user_id = 1; select * from profiles where user_id = 2; … select * from profiles where user_id = 10;
users { id profile { name } } N+1問題 –
usersに対応するprofileを事前ロード # Ruby code def resolve User.all.preload(:profile) end
users { id profile { name } } N+1問題 –
usersは10件Hit select * from users; – hitしたusersに対応したprofilesを事前ロード select * from profiles where user_id in (1, 2, …, 10);
users { id } N+1問題 – usersは10件Hit select * from
users; – fieldに指定していなくてもprofilesを事前ロー ドしてしまう select * from profiles where user_id in (1, 2, …, 10);
users { id profile { name } } N+1問題 –
usersに対応するprofileを遅延ロード # Ruby code def resolve # fieldにprofileがある場合、profile を取得するuser_idを記憶しておき、最後にま とめて取得する User.all end
N+1問題 – 事前ロード🙅 – 指定していないfieldも読み込んでしまう – 遅延ロード🙆 – 指定されたfieldのみまとめて取得
無駄な計算
user(id:$id) { id reviewCount } 無駄な計算 – userを1件返却するQuery – userが投稿したレビュー数を取得
– reviewsテーブルをcount # Ruby code def resolve(id:) user = User.find_by(id:) { id: user.id, review_count: user.reviews.count, } end
user(id:$id) { id reviewCount } 無駄な計算 – users select *
from users where id = 1; – reviews select count(*) from reviews where user_id = 1;
user(id:$id) { id } 無駄な計算 – reviewCountを指定していなくても reviews.countが計算される # Ruby
code def resolve(id:) user = User.find_by(id:) { id: user.id, review_count: user.reviews.count, } end
user(id:$id) { id } 無駄な計算 – reviewCountを指定していなくても reviews.countが計算される # Ruby
code def resolve(id:) user = User.find_by(id:) { id: user.id, review_count: user.reviews.count, } end reviewCountが指定されているときだけ、 reviews.countが計算されるような実装に変 更する!
無駄な計算 – 常に全てのfieldを計算してしまう🙅 – 指定されたfieldのみ計算🙆
直列で取得
hoge { heavy1 heavy2 } 直列で取得 – heavy1やheavy2は重い処理 – レスポンスまでheavy1+heavy2の処理時間
# Ruby code def resolve { heavy1: Hoge.heavy1_process, heavy2: Hoge.heavy2_process, } end
hoge { heavy1 heavy2 } 直列で取得 – heavy1とheavy2は同時に行われるので遅い 方の時間がレスポンスタイムとなる #
Ruby code def resolve # heavy1, 2を非同期で取得 heavy1 = Hoge.sync_heavy1_process heavy2 = Hoge.sync_heavy2_process { heavy1:, heavy2:, } end
直列で取得 – 直列だと重い場合は並列取得を検討🙆 – 直列でも十分速い場合は問題なし! – 並列取得にすると実装の複雑度が上がるのでメ リットがない場合はやらない方が良い
まとめ
- N+1問題 - 遅延ロードを検討する - 無駄な計算 - fieldが指定されているときだけ計算する - 重いfield
- 並列実行を検討する まとめ