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
24
7k
顧客が本当に必要だったもの - パフォーマンス改善編 / 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
78
31k
アプリケーションが 正しく動作するということ - 自動テスト編 / Automated Testing
soudai
15
3k
Gitlab本から学んだこと - そーだいなるプレイバック / gitlab-book
soudai
8
1.7k
**強い**エンジニアのなり方 - フィードバックサイクルを勝ち取る / grow one day each day
soudai
116
110k
マルチテナントの実現におけるDB設計とRLS / Utilizing RSL in multi-tenancy
soudai
26
8.2k
キャッシュと向き合う、キャッシュと共に生きる / cache pattern
soudai
37
15k
RDBアンチパターンと戦う - 削除フラグ 完全攻略ガイド / delete flag
soudai
30
18k
コミュニティと共に生きる - キャリアの螺旋 / live with community
soudai
8
5.8k
今年1年間の”アウトプット”を振り返る / soudai's output - 2023
soudai
15
2.3k
Other Decks in Technology
See All in Technology
Amazon CloudWatch Network Monitor 導入ガイド_デモ説明付き
yukimmmm
0
130
「視座」の上げ方が成人発達理論にわかりやすくまとまってた / think_ perspective_hidden_dimensions
shuzon
2
13k
AIを駆使したゲーム開発戦略: 新設AI組織の取り組み / sge-ai-strategy
cyberagentdevelopers
PRO
1
140
いまならこう作りたい AWSコンテナ[本格]入門ハンズオン 〜2024年版 ハンズオンの構想〜
horsewin
10
2.2k
株式会社ドクターズプライム 会社紹介資料 - エンジニア向け
drsprime
0
180
Shift-from-React-to-Vue
calm1205
4
1.5k
いろんなものと両立する Kaggleの向き合い方
go5paopao
1
370
ガチ勢によるPipeCD運用大全〜滑らかなCI/CDを添えて〜 / ai-pipecd-encyclopedia
cyberagentdevelopers
PRO
3
240
RAGのためのビジネス文書解析技術
eida
3
450
신뢰할 수 있는 AI 검색 엔진을 만들기 위한 Liner의 여정
huffon
0
460
Microsoft Fabric OneLake の実体について
ryomaru0825
0
110
Postmanの日本市場におけるDevRel (的) 活動 / Postman's DevRelish activities in Japan
yokawasa
1
110
Featured
See All Featured
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
A designer walks into a library…
pauljervisheath
202
24k
[RailsConf 2023] Rails as a piece of cake
palkan
51
4.9k
Embracing the Ebb and Flow
colly
84
4.4k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
664
120k
The Invisible Side of Design
smashingmag
297
50k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
Building Applications with DynamoDB
mza
90
6.1k
VelocityConf: Rendering Performance Case Studies
addyosmani
325
24k
4 Signs Your Business is Dying
shpigford
180
21k
Being A Developer After 40
akosma
86
590k
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 ↓ 常に追求した者だけが辿り着ける
まとめ 本当に必要なモノを実装する
まとめ 本当に必要なモノを実装する ↓ そのためにプロダクト、ドメインと向き合う
まとめ
まとめ 質を追求した結果 パフォーマンスは後からついてくる
良いソフトウェアを作ろう 目の前のプロダクトに向き合おう まとめ
昨日の自分に誇れる 今日の自分になろう まとめ
ご清聴ありがとうございました まとめ