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
600
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
GraphQL データ取得高速化
tsukiji.graphql #1での発表資料です。
https://tsukiji-graphql.connpass.com/event/281413/
ham
July 06, 2023
More Decks by ham
See All by ham
プロダクト開発から業務改善コンサルまで。事業全体へ「染み出す」ことで広がるエンジニアの可能性
ham0215
0
170
AI時代に「チーム開発」を見直す ~個人アサインへのシフトと、AI駆動開発の実践例~
ham0215
0
63
機能開発を止めないために!運用と開発のバランスを可視化するために使っている指標をご紹介
ham0215
0
63
未来のAI駆動開発をイメージしながらAI開発基盤を整備する
ham0215
1
180
AIと過ごす1日〜全業務フローにAIを組み込む実践ガイド〜
ham0215
0
160
生成AIによる生産性向上〜テック企業やファインディの活用事例〜
ham0215
1
140
生成AI導入の効果を最大化する データ活用戦略
ham0215
0
640
データ駆動経営の道しるべ:プロダクト開発指標の戦略的活用法
ham0215
2
560
開発組織における意思決定の実例〜開発優先度・組織構成・ツール導入〜
ham0215
0
140
Featured
See All Featured
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.3k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
300
Visualization
eitanlees
152
17k
Unsuck your backbone
ammeep
672
58k
Building the Perfect Custom Keyboard
takai
2
860
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.5k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
410
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
470
Statistics for Hackers
jakevdp
799
230k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
320
Building a Scalable Design System with Sketch
lauravandoore
463
34k
ラッコキーワード サービス紹介資料
rakko
1
4.7M
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
- 並列実行を検討する まとめ