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
顧客が本当に必要だったもの - パフォーマンス改善編 / Make what is needed
Search
soudai sone
October 29, 2024
Technology
30
8.4k
顧客が本当に必要だったもの - パフォーマンス改善編 / Make what is needed
# 失敗から学ぶRDBの正しい歩き方
-
https://amzn.to/4e0CqfH
soudai sone
October 29, 2024
Tweet
Share
More Decks by soudai sone
See All by soudai sone
仕事を前に進めるためのコツ - 判断と決断と共有 / Aim for the goal
soudai
84
36k
アプリケーションが 正しく動作するということ - 自動テスト編 / Automated Testing
soudai
15
3.1k
Gitlab本から学んだこと - そーだいなるプレイバック / gitlab-book
soudai
8
1.8k
**強い**エンジニアのなり方 - フィードバックサイクルを勝ち取る / grow one day each day
soudai
120
110k
マルチテナントの実現におけるDB設計とRLS / Utilizing RSL in multi-tenancy
soudai
26
8.2k
キャッシュと向き合う、キャッシュと共に生きる / cache pattern
soudai
38
16k
RDBアンチパターンと戦う - 削除フラグ 完全攻略ガイド / delete flag
soudai
30
18k
コミュニティと共に生きる - キャリアの螺旋 / live with community
soudai
8
5.9k
今年1年間の”アウトプット”を振り返る / soudai's output - 2023
soudai
15
2.4k
Other Decks in Technology
See All in Technology
Amazon CloudWatch Network Monitor のススメ
yuki_ink
1
210
OCI Security サービス 概要
oracle4engineer
PRO
0
6.5k
IBC 2024 動画技術関連レポート / IBC 2024 Report
cyberagentdevelopers
PRO
1
110
OCI 運用監視サービス 概要
oracle4engineer
PRO
0
4.8k
第1回 国土交通省 データコンペ参加者向け勉強会③- Snowflake x estie編 -
estie
0
130
強いチームと開発生産性
onk
PRO
35
11k
SRE×AIOpsを始めよう!GuardDutyによるお手軽脅威検出
amixedcolor
0
160
ノーコードデータ分析ツールで体験する時系列データ分析超入門
negi111111
0
420
SREが投資するAIOps ~ペアーズにおけるLLM for Developerへの取り組み~
takumiogawa
1
420
OCI Vault 概要
oracle4engineer
PRO
0
9.7k
The Rise of LLMOps
asei
7
1.7k
適材適所の技術選定 〜GraphQL・REST API・tRPC〜 / Optimal Technology Selection
kakehashi
1
690
Featured
See All Featured
Designing on Purpose - Digital PM Summit 2013
jponch
115
7k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
47
2.1k
Writing Fast Ruby
sferik
627
61k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
246
1.3M
KATA
mclloyd
29
14k
Faster Mobile Websites
deanohume
305
30k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Why You Should Never Use an ORM
jnunemaker
PRO
54
9.1k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.1k
The World Runs on Bad Software
bkeepers
PRO
65
11k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
Transcript
【ハイブリッド開催】わたし史上、最高のチューニング 顧客が本当に必要だったもの - パフォーマンス改善編
What is it?
結論:仕様を正しく変更するのが 一番パフォーマンスに効く What is it?
What is it?
ずっと同じことを言ってる What is it?
ずっと同じことを言ってる ↓ 今日はもうちょっと具体例の話 What is it?
1. 自己紹介 2. 複雑な仕様がRDBを殺す 3. 特効薬 : 仕様を削る 4. まとめ
あじぇんだ
1. 自己紹介 2. 複雑な仕様がRDBを殺す 3. 特効薬 : 仕様を削る 4. まとめ
あじぇんだ
自己紹介 曽根 壮大(40歳) Have Fun Tech LLC 代表社員 株式会社リンケージ CTO
兼 COO そ • 日本PostgreSQLユーザ会 勉強会分科会 担当 • 3人の子供がいます(長女、次女、長男) • 技術的にはWeb/LL言語/RDBMSが好きです • コミュニティが好き たけ ね とも
1. 自己紹介 2. 複雑な仕様がRDBを殺す 3. 特効薬 : 仕様を削る 4. まとめ
あじぇんだ
複雑な仕様がスロークエリや ロングトランザクションを生む 複雑な仕様がRDBを殺す
複雑な仕様がRDBを殺す
複雑な仕様がRDBを殺す
これは本当に闇が深い 複雑な仕様がRDBを殺す
ECサイトの例 複雑な仕様がRDBを殺す
ECサイトの例 ↓ 購入のボタンがめちゃ重い 複雑な仕様がRDBを殺す
1. 商品の在庫を確保 2. ポイントの利用 3. クーポンの利用 4. キャンペーンの確認 5. 決済処理
6. 配送手続き処理 7. ポイント付与 8. 購入履歴の追加 9. 通知処理 複雑な仕様がRDBを殺す これを全部 1つのトランザクションまとめる
1. 商品の在庫を確保 2. ポイントの利用 3. クーポンの利用 4. キャンペーンの確認 5. 決済処理
6. 配送手続き処理 7. ポイント付与 8. 購入履歴の追加 9. 通知処理 複雑な仕様がRDBを殺す これを全部 1つのトランザクションまとめる いきなりUPDATEとかで ロックを取ると後続が詰まる
1. 商品の在庫を確保 2. ポイントの利用 3. クーポンの利用 4. キャンペーンの確認 5. 決済処理
6. 配送手続き処理 7. ポイント付与 8. 購入履歴の追加 9. 通知処理 複雑な仕様がRDBを殺す これを全部 1つのトランザクションまとめる 処理の数だけクエリを投げて集計する
1. 商品の在庫を確保 2. ポイントの利用 3. クーポンの利用 4. キャンペーンの確認 5. 決済処理
6. 配送手続き処理 7. ポイント付与 8. 購入履歴の追加 9. 通知処理 複雑な仕様がRDBを殺す これを全部 1つのトランザクションまとめる 処理の数だけクエリを投げて集計する 無理に1回のクエリで対応しようとして、 超複雑なクエリが生まれる
1. 商品の在庫を確保 2. ポイントの利用 3. クーポンの利用 4. キャンペーンの確認 5. 決済処理
6. 配送手続き処理 7. ポイント付与 8. 購入履歴の追加 9. 通知処理 複雑な仕様がRDBを殺す これを全部 1つのトランザクションまとめる 処理の数だけクエリを投げて集計する 無理に1回のクエリで対応しようとして、 超複雑なクエリが生まれる さらにN+1のループがあったりする
1. 商品の在庫を確保 2. ポイントの利用 3. クーポンの利用 4. キャンペーンの確認 5. 決済処理
6. 配送手続き処理 7. ポイント付与 8. 購入履歴の追加 9. 通知処理 複雑な仕様がRDBを殺す これを全部 1つのトランザクションまとめる 外部APIだったりする
1. 商品の在庫を確保 2. ポイントの利用 3. クーポンの利用 4. キャンペーンの確認 5. 決済処理
6. 配送手続き処理 7. ポイント付与 8. 購入履歴の追加 9. 通知処理 複雑な仕様がRDBを殺す これを全部 1つのトランザクションまとめる 外部APIだったりする しかも時々めちゃレスポンスが遅い ISUCON9の予選問題がこれ
1. 商品の在庫を確保 2. ポイントの利用 3. クーポンの利用 4. キャンペーンの確認 5. 決済処理
6. 配送手続き処理 7. ポイント付与 8. 購入履歴の追加 9. 通知処理 複雑な仕様がRDBを殺す これを全部 1つのトランザクションまとめる ここも外部APIだったりする 失敗したりするとロールバックでやり直し ここが終わってやっと画面遷移が終わる
全部を同時実行する必要はない 複雑な仕様がRDBを殺す
全部を同時実行する必要はない ↓ ユーザが知りたいのは購入できた事実 複雑な仕様がRDBを殺す
1. 商品の在庫を確保 2. ポイントの利用 3. クーポンの利用 4. キャンペーンの確認 5. 決済処理
6. 配送手続き処理 7. ポイント付与 8. 購入履歴の追加 9. 通知処理 複雑な仕様がRDBを殺す 在庫を確保できば後続は非同期にできる
1. 商品の在庫を確保 2. ポイントの利用 3. クーポンの利用 4. キャンペーンの確認 5. 決済処理
6. 配送手続き処理 7. ポイント付与 8. 購入履歴の追加 9. 通知処理 複雑な仕様がRDBを殺す 後続で処理して 失敗したら購入を取り消す
1. 商品の在庫を確保 2. ポイントの利用 3. クーポンの利用 4. キャンペーンの確認 5. 決済処理
6. 配送手続き処理 7. ポイント付与 8. 購入履歴の追加 9. 通知処理 複雑な仕様がRDBを殺す 商品次第ではここさえ確定できれば、 あとは非同期にできる
ロングトランザクション対策 複雑な仕様がRDBを殺す
ロングトランザクション対策 ↓ 分割する 複雑な仕様がRDBを殺す
???「でも全部同じテーブルなんですよ」 複雑な仕様がRDBを殺す
複雑な仕様がRDBを殺す
???「でも全部同じテーブルなんですよ」 ↓ ライフサイクルに合わせてテーブルは分割 複雑な仕様がRDBを殺す
ちゃんと正規化する 責務を正しく分ける 複雑な仕様がRDBを殺す
ここまでシンプルな実装を目指しましょうと強調してきました が、「シンプルな実装」とはなんでしょうか。RDBMSを使う上で シンプルな実装のヒントは正規化です。正規化のコツは次の ように表現できます。 • 事実だけを保存する • 重複がない
• 不整合がない • nullがない これらを意識して設計していくとシンプルな設計に近づいてい きます。 また正規化を行う際はここまで説明したとおり、種別と状態を 考えることも重要です。ライフサイクルが違うデータは往々に して状態や種別が異なります。 場合によってはnullになるよう なカラムやUPDATEが必要なレコードは状態を持っている可 能性があります。こうしたテーブルが見つかった場合はより 深く考察する必要があります。 https://agilejourney.uzabase.com/entry/2022/07/28/103000
そして最後にINDEXの数にも注目しましょう。主キーは必ずあ りますが、外部キー制約とユニーク制約を除いたINDEXは主 に検索のために必要なINDEXです。検索のWHEREの対象の 数だけそのテーブルの責務が大きいといえ、4つ以上の INDEXが必要な場合も同じく深く考察する必要があります。隠 れた状態をWHEREで絞り込んでいたり、種別をWHEREで絞り 込んでいるケースが見えてくることがあります。 このようにシンプルな設計を目指して考察を繰り返していくこ とが重要です。そして同じくらい重要なこととして認識すべき
はイージーとシンプルは両立できる、ということです。 シンプ ルを目指し考察を繰り返すことがまさにデータモデリングであ り、変化に強い設計につながっていくのです。 https://agilejourney.uzabase.com/entry/2022/07/28/103000
複雑な仕様がRDBを殺す
1. 自己紹介 2. 複雑な仕様がRDBを殺す 3. 特効薬 : 仕様を削る 4. まとめ
あじぇんだ
特効薬:仕様を削る
ずっとこれ言ってる 特効薬:仕様を削る
ずっとこれ言ってる ↓ 代表格を紹介します 特効薬:仕様を削る
ページャの原罪 特効薬:仕様を削る
ページャの原罪 ↓ ページャの業は深い 特効薬:仕様を削る
1つ目 対象総件数の表示 特効薬:仕様を削る
特効薬:仕様を削る
特効薬:仕様を削る このcount(*)が不要なクエリを生む
特効薬:仕様を削る 今はGoogleも表示していない
sql_culc_found_rows の呪い 特効薬:仕様を削る
sql_culc_found_rows の呪い 特効薬:仕様を削る MySQLで全体件数を取得するために使われていた MySQL 8.0.17で非推奨になった
通知の未読件数とかも一緒 基本的には未読かどうかわかれば良い 特効薬:仕様を削る アプリ 999 数字は不要
INDEXが活用できないcount()は めちゃめちゃ遅い 特効薬:仕様を削る テーブルスキャンだから
INDEXが活用できないcount()は めちゃめちゃ遅い 特効薬:仕様を削る テーブルスキャンだから 複雑な検索フォームの場合 テーブルスキャンになるケースで刺さる
2つ目 最終ページのリンク 特効薬:仕様を削る
特効薬:仕様を削る
ORDER BYの LIMIT OFFSETに刺さる 特効薬:仕様を削る
特効薬:仕様を削る
特効薬:仕様を削る
最終ページに行きたい? 昇順、降順で良い 特効薬:仕様を削る
そもそもユーザが必要なのは 検索フォームだったりする 特効薬:仕様を削る
そもそもユーザが必要なのは 検索フォームだったりする 特効薬:仕様を削る これもこれで闇が深いが … 部分一致とかORとか…
これらは単純に仕様を消せば 実装不要でパフォーマンスも改善する 特効薬:仕様を削る
特効薬:仕様を削る
What is it? 必要最小限を提供する
本当に必要なモノだけを 実装していますか? 特効薬:仕様を削る
1. 自己紹介 2. 複雑な仕様がRDBを殺す 3. 特効薬 : 仕様を削る 4. まとめ
あじぇんだ
複雑な仕様がRDBを殺す
まとめ Simple is Beautiful
まとめ Simple is Beautiful ↓ 常に追求した者だけが辿り着ける
まとめ 本当に必要なモノを実装する
まとめ 本当に必要なモノを実装する ↓ そのためにプロダクト、ドメインと向き合う
まとめ
まとめ 質を追求した結果 パフォーマンスは後からついてくる
良いソフトウェアを作ろう 目の前のプロダクトに向き合おう まとめ
昨日の自分に誇れる 今日の自分になろう まとめ
ご清聴ありがとうございました まとめ