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
270
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
開発パフォーマンスを最大化するための開発体制
ham0215
7
1.3k
今こそ思い出すGraphQLの特徴
ham0215
0
70
DevOpsメトリクスとアウトカムの接続にトライ!開発プロセスを通して計測できるメトリクスの活用方法
ham0215
2
280
CIは5分以内!素早い開発サイクルを支えるCI
ham0215
0
2.7k
現場主導で取り組む継続的な技術的負債の解消
ham0215
4
4.1k
可視化からはじめる開発生産性向上への道のり
ham0215
0
330
キーボードのすゝめ.pdf
ham0215
0
110
イージーからシンプルへ 〜プロダクトの成長に合わせたアーキテクチャの変更〜
ham0215
0
3.4k
[After RubyKaigi]クリスマスを待たずに Rust版YJITの実力を検証
ham0215
0
180
Featured
See All Featured
Infographics Made Easy
chrislema
238
18k
Git: the NoSQL Database
bkeepers
PRO
423
63k
Fantastic passwords and where to find them - at NoRuKo
philnash
39
2.5k
StorybookのUI Testing Handbookを読んだ
zakiyama
13
4.7k
No one is an island. Learnings from fostering a developers community.
thoeni
16
2.1k
It's Worth the Effort
3n
180
27k
Making Projects Easy
brettharned
109
5.5k
Fashionably flexible responsive web design (full day workshop)
malarkey
398
65k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
123
39k
Why Our Code Smells
bkeepers
PRO
331
56k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
82
45k
Visualization
eitanlees
137
14k
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
- 並列実行を検討する まとめ