Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
2024/05/10 RubyKaigi 2024 直前LT祭 株式会社タイミー 新谷哲平 そろそろ理解する includes @euglena1215
Slide 2
Slide 2 text
自己紹介 新谷 哲平(@euglena1215) ● 株式会社タイミー ● バックエンド テックリード ○ 2024/04/01~ New! ● GWにRBS入門しました
Slide 3
Slide 3 text
自己紹介 新谷 哲平(@euglena1215) ● 株式会社タイミー ● バックエンド テックリード ○ 2024/04/01~ New! ● GWにRBS入門しました
Slide 4
Slide 4 text
RBS という名前を聞いて パッと思いつく型(方)は... 突然ですが
Slide 5
Slide 5 text
No content
Slide 6
Slide 6 text
宣伝 Ruby AST に親しみがない人向け Ruby AST を見たときに身構えないようになることがゴール。
Slide 7
Slide 7 text
宣伝 Ruby AST に親しみがない人向け Ruby AST を見たときに身構えないようになることがゴール。 タイミーはRBSやっていくぞ! 💪 💪 💪
Slide 8
Slide 8 text
宣伝 Ruby AST に親しみがない人向け Ruby AST を見たときに身構えないようになることがゴール。
Slide 9
Slide 9 text
2024/05/10 RubyKaigi 2024 直前LT祭 株式会社タイミー 新谷哲平 そろそろ理解する includes @euglena1215
Slide 10
Slide 10 text
みなさんに質問 AR::Relation#includes 使ってますか?
Slide 11
Slide 11 text
みなさんに質問 - 使っている方 AR::Relation#includesの 挙動を理解して使っていますか?
Slide 12
Slide 12 text
みなさんに質問 - 使っていない方 AR::Relation#includesの挙動を 理解した上で使わない選択をしてますか?
Slide 13
Slide 13 text
自分のincludesに対する認識 内部的にいい感じに preload と eager_load を使い分けてるんでしょ? どう使い分けてるかよく知らないし、 とりあえず preload 使っとくか...
Slide 14
Slide 14 text
こうなりたい AR::Relation#includesの挙動を完全理解! コードを読めばどんなクエリが 発行されるか一発でわかる!
Slide 15
Slide 15 text
1 結論
Slide 16
Slide 16 text
ひとことでまとめるの無理でした 😢 これからクイズ形式でincludesの挙動を一緒に理解しましょう! 結論
Slide 17
Slide 17 text
2 includes クイズ
Slide 18
Slide 18 text
サンプルコードを表示するのでどんなクエリが発行されるか考えてみましょう! こちらから手元で動かすことができます https://gist.github.com/euglena1215/fb6cd1235278491dc206b9bd6feaf71e includes クイズ
Slide 19
Slide 19 text
クイズで使われるコードのモデル定義はこんな感じ includes クイズ
Slide 20
Slide 20 text
includes クイズ① Q. どんなクエリが発行されるでしょうか?
Slide 21
Slide 21 text
includes クイズ① Q. どんなクエリが発行されるでしょうか? A. preload 相当の分割されたクエリが発行される
Slide 22
Slide 22 text
1. 全てのケース → preload 判定ルール
Slide 23
Slide 23 text
includes クイズ② Q. どんなクエリが発行されるでしょうか?
Slide 24
Slide 24 text
includes クイズ② Q. どんなクエリが発行されるでしょうか? ここがポイント!
Slide 25
Slide 25 text
includes で指定したフィールドを使って絞り込みたいときに使うメソッド 📝 references ってなんだ?
Slide 26
Slide 26 text
includes で指定したフィールドを使って絞り込みたいときに使うメソッド 📝 references ってなんだ? ただし、where に文字列ではなくHashで渡せば references は省略可能
Slide 27
Slide 27 text
includes クイズ② Q. どんなクエリが発行されるでしょうか?
Slide 28
Slide 28 text
includes クイズ② Q. どんなクエリが発行されるでしょうか? A. eager_load 相当の LEFT OUTER JOIN で結合されたクエリ
Slide 29
Slide 29 text
1. 全てのケース → preload 判定ルール
Slide 30
Slide 30 text
1. includes 先に references を使っている → eager_load 2. それ以外 → preload 判定ルール
Slide 31
Slide 31 text
1. includes 先に references を使っている → eager_load 2. includes 先に joins を使っている → eager_load 3. それ以外 → preload 判定ルール joins も同じ挙動
Slide 32
Slide 32 text
includes クイズ③ Q. どんなクエリが発行されるでしょうか?
Slide 33
Slide 33 text
includes クイズ③ Q. どんなクエリが発行されるでしょうか? ここがポイント!
Slide 34
Slide 34 text
includes クイズ③ Q. どんなクエリが発行されるでしょうか? A. LEFT OUTER JOIN で結合しつつ、comments.id = 1 での絞り込みが行われる
Slide 35
Slide 35 text
1. includes 先に references を使っている → eager_load 2. includes 先に joins を使っている → eager_load 3. それ以外 → preload 判定ルール
Slide 36
Slide 36 text
1. includes 先に references を使っている → eager_load 2. includes 先に joins を使っている → eager_load 3. includes 先で絞り込みを Hash 形式で行っている → eager_load 4. それ以外 → preload 判定ルール
Slide 37
Slide 37 text
includes クイズ④ Q. どんなクエリが発行されるでしょうか?
Slide 38
Slide 38 text
includes クイズ④ Q. どんなクエリが発行されるでしょうか? ここがポイント!
Slide 39
Slide 39 text
includes クイズ④ Q. どんなクエリが発行されるでしょうか? A. author も eager_load 相当の LEFT OUTER JOIN で結合される
Slide 40
Slide 40 text
includes クイズ④ Q. どんなクエリが発行されるでしょうか? A. author も eager_load 相当の LEFT OUTER JOIN で結合される preload と同様 author(user) は クエリが分割されるものだと思ってました 😇
Slide 41
Slide 41 text
1. includes 先に references を使っている → eager_load 2. includes 先に joins を使っている → eager_load 3. includes 先で絞り込みを Hash 形式で行っている → eager_load 4. それ以外 → preload 判定ルール
Slide 42
Slide 42 text
1. includes 先に references を使っている → eager_load 2. includes 先に joins を使っている → eager_load 3. includes 先で絞り込みを Hash 形式で1つ以上行っている → 全部 eager_load 4. それ以外 → preload 判定ルール
Slide 43
Slide 43 text
1. includes 先に references を1つ以上使っている → 全部 eager_load 2. includes 先に joins を1つ以上使っている → 全部 eager_load 3. includes 先で絞り込みを Hash 形式で1つ以上行っている → 全部 eager_load 4. それ以外 → preload 判定ルール references, joins も同様の挙動
Slide 44
Slide 44 text
includes クイズ⑤ Q. どんなクエリが発行されるでしょうか?
Slide 45
Slide 45 text
includes クイズ⑤ Q. どんなクエリが発行されるでしょうか? ここがポイント!
Slide 46
Slide 46 text
includes クイズ⑥ Q. どんなクエリが発行されるでしょうか? A. author も eager_load 相当の LEFT OUTER JOIN での結合が行われる
Slide 47
Slide 47 text
1. includes 先に references を1つ以上使っている → 全部 eager_load 2. includes 先に joins を1つ以上使っている → 全部 eager_load 3. includes 先で絞り込みを Hash 形式で1つ以上行っている → 全部 eager_load 4. それ以外 → preload 判定ルール
Slide 48
Slide 48 text
1. includes 先に references を1つ以上使っている → 全部 eager_load 2. includes 先に joins を1つ以上使っている → 全部 eager_load 3. includes 先で絞り込みを Hash 形式で1つ以上行っている → 全部 eager_load 4. eager_load を併用している → 全部 eager_load 5. それ以外 → preload 判定ルール
Slide 49
Slide 49 text
1. includes 先に references を1つ以上使っている → 全部 eager_load 2. includes 先に joins を1つ以上使っている → 全部 eager_load 3. includes 先で絞り込みを Hash 形式で1つ以上行っている → 全部 eager_load 4. eager_load を併用している → 全部 eager_load 5. それ以外 → preload 判定ルール 完成 🎉🎉🎉 したはず...間違いあればこっそり教えてください
Slide 50
Slide 50 text
1. includes 先に references を1つ以上使っている → 全部 eager_load 2. includes 先に joins を1つ以上使っている → 全部 eager_load 3. include先で絞り込みを Hash形式で1つ以上行っている → 全部 eager_load 4. eager_load を併用している → 全部 eager_load 5. それ以外 → preload 判定ルール 完成 🎉🎉🎉 したはず...間違いあればこっそり教えてください このルール結構厳しくない?🤔
Slide 51
Slide 51 text
includes クイズ 仮にこういった実装がされているとすると... preload 相当の複数のクエリ(3つ)が発行される
Slide 52
Slide 52 text
includes クイズ 例えば何かの機能変更で eager_load を追加すると...
Slide 53
Slide 53 text
includes クイズ⑤ includes 先のフィールドを1つ使って絞り込むよう変更すると... 巨大な1つのクエリに💥
Slide 54
Slide 54 text
1つのクエリになって問題ある? ● パフォーマンスの制御が困難 ○ クエリが大きく変化するので、利用するインデックスも変化するかも
Slide 55
Slide 55 text
1つのクエリになって問題ある? ● パフォーマンスの制御が困難 ○ クエリが大きく変化するので、利用するインデックスも変化するかも ● 変化に本番リリース前に気付くのが難しい ○ 普段発行されるクエリを検証するテストを書いていますか? ○ 十分なデータ量がないQA環境で試しても問題が顕在化しないかも
Slide 56
Slide 56 text
1つのクエリになって問題ある? ● パフォーマンスの制御が困難 ○ クエリが大きく変化するので、利用するインデックスも変化するかも ● 変化に本番リリース前に気付くのが難しい ○ 普段発行されるクエリを検証するテストを書いていますか? ○ 十分なデータ量がないQA環境で試しても問題が顕在化しないかも ● そもそもこのクエリを意図していた?
Slide 57
Slide 57 text
1つのクエリになって問題ある? ● 実行計画が大きく変化する ○ 突然パフォーマンスが急激に悪化する可能性 ● 実装者が本番リリース前に気付くのが難しい ○ 自動テストは通ってしまう 個人的にはこちらを期待していた
Slide 58
Slide 58 text
● いずれかのルールによって突然全てが eager_load 相当として扱われ、 1つのクエリになるのは大変厳しい ● パフォーマンス上の意図がなければ基本的には preload を使い、同時に絞り 込みを行いたいときだけ eager_load を使う方が無難そう ● includes が部分的に preload 相当の挙動をしてくれるといいな... 🥺 自分の考え
Slide 59
Slide 59 text
● いずれかのルールによって突然全てが eager_load 相当として扱われ、 1つのクエリになるのは大変厳しい ● パフォーマンス上の意図がなければ基本的には preload を使い、同時に絞り 込みを行いたいときだけ eager_load を使う方が無難そう ● includes が部分的に preload 相当の挙動をしてくれるといいな... 🥺 自分の考え みなさんのincludesへの向き合い方を ぜひXで教えてください! #RubyKaigi2024_直前LT祭