Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GraphQL データ取得高速化

ham
July 06, 2023
390

GraphQL データ取得高速化

tsukiji.graphql #1での発表資料です。
https://tsukiji-graphql.connpass.com/event/281413/

ham

July 06, 2023
Tweet

More Decks by ham

Transcript

  1. users { id profile { name } } N+1問題 –

    userを複数返却するQuery – id fieldはusersテーブルから取得 – profileはprofilesテーブルから取得 # Ruby code def resolve User.all end
  2. 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;
  3. users { id profile { name } } N+1問題 –

    usersに対応するprofileを事前ロード # Ruby code def resolve User.all.preload(:profile) end
  4. 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);
  5. users { id } N+1問題 – usersは10件Hit select * from

    users; – fieldに指定していなくてもprofilesを事前ロー ドしてしまう select * from profiles where user_id in (1, 2, …, 10);
  6. users { id profile { name } } N+1問題 –

    usersに対応するprofileを遅延ロード # Ruby code def resolve # fieldにprofileがある場合、profile を取得するuser_idを記憶しておき、最後にま とめて取得する User.all end
  7. 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
  8. user(id:$id) { id reviewCount } 無駄な計算 – users select *

    from users where id = 1; – reviews select count(*) from reviews where user_id = 1;
  9. 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
  10. 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が計算されるような実装に変 更する!
  11. hoge { heavy1 heavy2 } 直列で取得 – heavy1やheavy2は重い処理 – レスポンスまでheavy1+heavy2の処理時間

    # Ruby code def resolve { heavy1: Hoge.heavy1_process, heavy2: Hoge.heavy2_process, } end
  12. hoge { heavy1 heavy2 } 直列で取得 – heavy1とheavy2は同時に行われるので遅い 方の時間がレスポンスタイムとなる #

    Ruby code def resolve # heavy1, 2を非同期で取得 heavy1 = Hoge.sync_heavy1_process heavy2 = Hoge.sync_heavy2_process { heavy1:, heavy2:, } end