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
B+木入門:PHPで理解する データベースインデックスの仕組み/b-plus-tree-101
Search
Ryo Tomidokoro
March 10, 2024
Technology
5
4.5k
B+木入門:PHPで理解する データベースインデックスの仕組み/b-plus-tree-101
PHPerKaigi 2024 の登壇資料です
Ryo Tomidokoro
March 10, 2024
Tweet
Share
More Decks by Ryo Tomidokoro
See All by Ryo Tomidokoro
集中して作業する技術/how_to_work_deeply
hanhan1978
61
40k
PHPでデータベースを作ってみた/create-data-with-php
hanhan1978
10
9.2k
ADRを一年運用してみた/adr_after_a_year
hanhan1978
8
3.4k
ADRを一年運用してみた/our_story_about_adr
hanhan1978
5
2k
PHPで学ぶ Session の基本と応用 / web-app-session-101-2024
hanhan1978
12
5.5k
レガシー回避のPHP開発術/avoid_php_legacy
hanhan1978
16
12k
Laravel Collectionの計算量を調べてみた2023/laravel_collection_time_complexity_2023
hanhan1978
1
1.4k
PHP で学ぶ Cache の距離の話 / study_cache_with_php
hanhan1978
7
2.2k
Laravel を低速化する技術 / how to slow laravel
hanhan1978
2
3.9k
Other Decks in Technology
See All in Technology
アジャイルチームがらしさを発揮するための目標づくり / Making the goal and enabling the team
kakehashi
3
170
CDCL による厳密解法を採用した MILP ソルバー
imai448
3
200
インフラとバックエンドとフロントエンドをくまなく調べて遅いアプリを早くした件
tubone24
1
440
Introduction to Works of ML Engineer in LY Corporation
lycorp_recruit_jp
0
150
TanStack Routerに移行するのかい しないのかい、どっちなんだい! / Are you going to migrate to TanStack Router or not? Which one is it?
kaminashi
0
630
Amplify Gen2 Deep Dive / バックエンドの型をいかにしてフロントエンドへ伝えるか #TSKaigi #TSKaigiKansai #AWSAmplifyJP
tacck
PRO
0
410
【令和最新版】AWS Direct Connectと愉快なGWたちのおさらい
minorun365
PRO
5
780
アジャイルでの品質の進化 Agile in Motion vol.1/20241118 Hiroyuki Sato
shift_evolve
0
190
OCI Vault 概要
oracle4engineer
PRO
0
9.8k
【LT】ソフトウェア産業は進化しているのか? #Agilejapan
takabow
0
110
マルチプロダクトな開発組織で 「開発生産性」に向き合うために試みたこと / Improving Multi-Product Dev Productivity
sugamasao
1
310
Lambda10周年!Lambdaは何をもたらしたか
smt7174
2
130
Featured
See All Featured
Scaling GitHub
holman
458
140k
Thoughts on Productivity
jonyablonski
67
4.3k
4 Signs Your Business is Dying
shpigford
180
21k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
25
1.8k
No one is an island. Learnings from fostering a developers community.
thoeni
19
3k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
1.9k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
Code Reviewing Like a Champion
maltzj
520
39k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
Automating Front-end Workflow
addyosmani
1366
200k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
Teambox: Starting and Learning
jrom
133
8.8k
Transcript
@hanhan1978 B+木入門:PHPで理解する データベースインデックスの仕組み PHPerKaigi 2024/03/09
@hanhan1978 • 富所 亮 • 所属 株式会社カオナビ CTO室 BackEnd Re-architecturing
Team (BERT) • 職業 バックエンドエンジニア • ブログ https://blog.hanhans.net • Yokohama North AM https://anchor.fm/yokohama-north-am 2
まず基礎的な知識から
B木の木って何?
コンピューターサイエンスにおける 基本的なデータ構造のひとつ https://en.wikipedia.org/wiki/Tree_(data_structure) 由来がわからない程度には基本
データ構造って? 言語によってはありえない質問かも
アルゴリズム + データ構造 プログラム
アルゴリズム + データ構造
アルゴリズム https://ja.wikipedia.org/wiki/アルゴリズム > アルゴリズムとは、解が定まっている「計算可能」問題 に対して、その解を正しく求める手続きをさす。あるいは それを形式的に表現したもの。
ようするにプログラム
アルゴリズム + データ構造
たとえば、PHPの配列 https://www.php.net/manual/ja/language.types.array.php
たとえば、PHPの配列 https://www.php.net/manual/ja/language.types.array.php
たとえば、PHPの配列 https://www.php.net/manual/ja/language.types.array.php 便利すぎる?
私達はもう自然に データ構造を使いこなしていた (過言)
余談 https://www.php.net/manual/ja/function.array-is-list.php 配列がリストかどうかをチェックする(錯乱)
PHPの配列は便利すぎるデータ構造 https://fortee.jp/phperkaigi-2023/proposal/e00788a4-ef25-49ee-b254-9d2b53e19633
PHPの配列は便利すぎるデータ構造2 https://tek.phparch.com/schedule
配列は便利すぎる データ構造としての用途ならSPL推奨
Standard PHP Library https://www.php.net/manual/ja/spl.datastructures.php
データ構造を意識するのはいつ?
• 低レイヤー • 競技プログラミング • 就活(leetcode) • パフォーマンス改善 PHPの仕事ではあんまりデータ構造を意識しないかも
LeetCode https://leetcode.com/
• 低レイヤー • 競技プログラミング • 就活(leetcode) • パフォーマンス改善 PHPの仕事ではあんまりデータ構造を意識しないかも
アルゴリズムだけだと どうしても改善できないことがある
そのため、やりたいことに合わせて データ構造とアルゴリズムを変える
例えば • [データ構造] リスト • [アルゴリズム] ループ PHPの文字列リストから、特定の文字を探す場合
例えば • [データ構造] リスト • [アルゴリズム] ループ PHPの文字列リストから、特定の文字を探す場合 O(N)
例えば • [データ構造] リスト • [アルゴリズム] Binary Search 整列されたデータであった場合
例えば • [データ構造] リスト • [アルゴリズム] Binary Search 整列されたデータであった場合 O(LogN)
計算量のおさらい https://www.techscore.com/blog/2016/08/08/開発新卒に捧ぐ、基本のアルゴリズムと計算量/
計算量 整列されてないデータ 整列されているデータ O(N) 単純ループ O(logN) Binary Search
アルゴリズム単体での限界 この先はデータ構造の助けがいる
例えば PHPでのよくある解決策としては 配列の値をhashのキーに置き換える
例えば • [データ構造] HashMap • [アルゴリズム] キーの存在チェック
例えば • [データ構造] HashMap • [アルゴリズム] キーの存在チェック O(1)
計算量のおさらい https://www.techscore.com/blog/2016/08/08/開発新卒に捧ぐ、基本のアルゴリズムと計算量/
ここまでのまとめ
アルゴリズムだけでは、限界があるの でデータ構造を工夫する必要がある
つまり、データ構造は向いているアル ゴリズムがある
C言語とか書いてた人は そりゃデータ構造いるだろ? 何いってんだ?となる
ここからB木の話
B木 1972年にBayerとMcCreightが発表した 論文 ORGANIZATION AND MAINTENANCE OF LARGE ORDERED INDICES
Boeing Research Labs に所属していた
B木の特徴 データアクセスを最小限にしつつ、データを効率的に保 存するためのデータ構造として生み出された。
B木の特徴 平衡木という特徴がある 二分木の場合 -> 偏った木になる可能性がある
偏った木
偏った木 ルートから3回の値比較が必要
平衡木
平衡木 全体の深さが同じになる
B木は挿入、削除で木の調整を行う
全体として バランスの取れた状態になる
ここでピンと来るかもしれない
B木は挿入、削除で木の調整を行う
データベースのインデックス追加時のコスト 平衡木はデータ追加時に木に調整が必要
5を加えたらどうなる?
これは平衡でない
高さが一定になるように調整される この”調整”がいわゆるコスト
このコストはどれくらいなのか?
5を加えることを考える
1. 挿入箇所を探す ルートからキーを比較して挿入箇所のノードを探す
2. 挿入処理を行う 探した挿入箇所にノードを追加する
3. ノード数が次数に達したら上にマージ 3,4,5で分裂した木をルートに向けてマージする
3. ノード数が次数に達したら上にマージ もし、ここも満杯になったら同じ処理を上に向かって繰り返す
O(logN) で探す + O(logN) でマージ
2 x O(logN) の計算量で インデックスの再構築が行われる
基本的にはデータを挿入するノードに 至るまでの経路上のノードに対して再 帰的に処理を行えば平衡が保たれる
経路外のノードは調整しない そこまで仕様は複雑じゃない
B木の特徴 また、もう一つの大きな特徴として 外部メモリ使用時の有用性
最近はインメモリデータベースなども ありますが、一般的にはデータベース はストレージ(HDD, SSD) にデータを 保存
OSのシステムコールはブロック単位で データの読み書きを行う 通常は4096バイト
必要なデータが1バイトだったとして も4096バイトの読み込み
昔のHDD ぐるぐる回るシリンダー から、データを読み取る ため、ブロック効率が良 くないともったいない! SSDで読み取りが早く なったとはいえ、無駄の ないデータIOはデータ ベースの鍵
B木はノードのサイズを設計可能 例えば 4バイト整数のキーで、ノード のインデックスも4バイトの場合
(4+4) x 2B = 8 x 512 = 4096 バイト
このように外部メモリに対してあらか じめデータ量を計算できる
なんでB木はデータベースインデック スで使われるの?
因果関係が逆
Randomに配置された大量の書類のイ ンデックスを効率的に管理するために 作られたのがB木
実際のB木の動き(デモ)
B+木 B木の特徴を保持しつつ、実用的な機能性を付加 論文 The Ubiquitous B-Tree
データ構造のイメージ
B+木 平衡を保つ基本的な仕組みはB木と同じ ただし、リーフノードにすべてのデータを保持
データ構造のイメージ リーフにすべてのデータが並ぶ
木の高さが変わってもリーフにすべてのデータが並ぶ
B+木の検索 3を探す場合は近傍のノードから到達
リーフがポインターを数珠つなぎにもつため 範囲検索も可能
検索 始点・終点でリーフだけで範囲を取得できる
カバリングインデックス(おまけ) インデックスのデータのみを取得する場合
カバリングインデックス(おまけ) インデックス検索以後の処理が必要ない
本当は実装が完了したリポジトリリンクを バシッと貼りたかったが 未完...orz 口でいうほど全然簡単じゃなかった
まとめ
データベースのインデックスが速いのは インデックスのデータ構造が専用につくら れているから
古典 インデックスサイズの正確な計算を実感するにはやはりC
安定のラムダノート この本には何度も命を救われている