SlideShare a Scribd company logo
1 of 129
Download to read offline
資料庫索引數據結構及主鍵設計 (B+Tree)
Database index data structure and primary key design (part1)
2016
Ant
yftzeng@gmail.com
2016
2/129
自我介紹
♪ Muzik Online (www.muzikair.com) 總工程師。
♪ Paganini+ (http://www.paganiniplus.com/) 技術長。
♪ BELP (fb.com/belp.general) 共同創辦人。
♪ CHROOT (www.chroot.org) 成員。
♪ 講師經驗
PHPConf, Modern Web Taiwan, MOPCON, WebConf, COSCUP, JSDC Taiwan,
DrupalCamp Taiwan, OSDC, HITCON, ...
♪ 略懂智慧財產權、資訊安全及軟體程式設計。
♪ 『略懂諸葛』。
♪ 沉浸於『人性』、『法律』與『科技』的三角關係中。
2016
3/129
問題 1: UUID ?
Q: 資料庫 Primary key 使用 UUID 比較快?
Serial/Auto-Increment
1
2
3
4
5
...
UUID
3a5e439b-eeb4-4074-8b23-51c2cdd35421
1bb19e6b-9c0c-475e-a7b3-f01a6b4cd496
af4c8b80-4bf5-4bf3-a4e3-a71bed920f10
e62acb5b-a393-4707-9aa5-90f79352eb4b
2e199d72-4e49-4ace-a504-419da63878f5
...
4/129
2016
問題 1: UUID ?
Q: 資料庫 Primary key 使用 UUID 比較快?
偽命題
2016
5/129
問題 1 ( 修正 ): MySQL UUID ?
Q: MySQL 的 Primary key 使用 UUID 比較快?
Serial/Auto-Increment
1
2
3
4
5
...
UUID
3a5e439b-eeb4-4074-8b23-51c2cdd35421
1bb19e6b-9c0c-475e-a7b3-f01a6b4cd496
af4c8b80-4bf5-4bf3-a4e3-a71bed920f10
e62acb5b-a393-4707-9aa5-90f79352eb4b
2e199d72-4e49-4ace-a504-419da63878f5
...
6/129
2016
問題 1 ( 修正 ): MySQL UUID ?
Q: MySQL 的 Primary key 使用 UUID 比較快?
偽命題
7/129
2016
問題 1 ( 修正 ): MySQL UUID ?
UUID 目前公定有五種版本:
➀ Version 1 (MAC address & date-time)
➁ Version 2 (DCE Security)
➂ Version 3 (MD5 hash & namespace)
➃ Version 4 (Random)
➄ Version 5 (SHA-1 hash & namespace)
Ref: https://en.wikipedia.org/wiki/Universally_unique_identifier
8/129
2016
問題 1 ( 修正 ): MySQL UUID ?
UUID 目前公定有五種版本:
➀ Version 1 (MAC address & date-time)
➁ Version 2 (DCE Security)
➂ Version 3 (MD5 hash & namespace)
➃ Version 4 (Random)
➄ Version 5 (SHA-1 hash & namespace)
Ref: https://en.wikipedia.org/wiki/Universally_unique_identifier
Version 2 未在 UUID 規格中定義,少見
9/129
2016
問題 1 ( 修正 ): MySQL UUID ?
UUID 目前公定有五種版本:
➀ Version 1 (MAC address & date-time)
➁ Version 2 (DCE Security)
➂ Version 3 (MD5 hash & namespace)
➃ Version 4 (Random)
➄ Version 5 (SHA-1 hash & namespace)
Ref: https://en.wikipedia.org/wiki/Universally_unique_identifier
10/129
2016
問題 1 ( 修正 ): MySQL UUID ?
UUID 類循序式 ( 通常後序產生的值 > 先前產生的值 ) :
➀ Version 1 (MAC address & date-time)
UUID 亂序式 ( 值的大小沒有前後關係 ) :
➂ Version 3 (MD5 hash & namespace)
➃ Version 4 (Random)
➄ Version 5 (SHA-1 hash & namespace)
11/129
2016
問題 1 ( 修正 ): MySQL UUID ?
UUIDv1 的範例:
2190718a-c7a3-61e2-aa34-024281ed9db5
2191f33e-c7a3-61e2-9b92-024281ed9db5
2192cc0a-c7a3-61e2-be4c-024281ed9db5
21939950-c7a3-61e2-9aad-024281ed9db5
21945ff2-c7a3-61e2-90fc-024281ed9db5
219525f4-c7a3-61e2-99df-024281ed9db5
Time
12/129
2016
問題 1 ( 修正 ): MySQL UUID ?
UUIDv4 的範例:
3a5e439b-eeb4-4074-8b23-51c2cdd35421
1bb19e6b-9c0c-475e-a7b3-f01a6b4cd496
af4c8b80-4bf5-4bf3-a4e3-a71bed920f10
e62acb5b-a393-4707-9aa5-90f79352eb4b
2e199d72-4e49-4ace-a504-419da63878f5
8cf2e49f-8ae9-43f2-a84d-78cb323114a3
Time
13/129
2016
問題 1 ( 修正 ): MySQL UUID ?
結論: UUID 可以是類循序式,也可以是亂序式。
但《循序式》與《亂序式》的重要性為何?
14/129
2016
問題 1 ( 修正 ): MySQL UUID ?
Ref: https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/
15/129
2016
問題 1 ( 修正 ): MySQL UUID ?
延伸 : GUID 與 UUID 的差異?
16/129
2016
問題 1 ( 修正 ): MySQL UUID ?
GUID 是 Microsoft 用詞,指的其實類似於 UUID ,
但實作方式不一樣。
Microsoft 對於 GUID 的實作至少有兩種:
➀ 基於 UuidCreate 的 NEWID(SQL) ;
➁ 基於 UuidCreateSequential 的 NEWSEQUENTIALID(SQL) 。
其中 NEWID 是亂序式,而 NEWSEQUENTIALID 是循序式。
2016
17/129
索引數據結構
18/129
2016
索引數據結構 : 無索引
目的:尋找【欄位一為 5 的資料】
操作: 5 , O(n)
缺點:總是需要全表掃描
資料表:
1 user1 pass1
2 user2 pass2
3 user3 pass3
4 user4 pass4
5 user5 pass5
19/129
2016
索引數據結構 : B-tree 索引
B-tree = Balanced tree (not Binary tree)
20/129
2016
索引數據結構 : B-tree 索引
目的:尋找【欄位一為 5 的資料】
操作: 4 , O(logbn)
缺點:全表掃描需要遍歷樹
資料表:
1 user1 pass1
2 user2 pass2
3 user3 pass3
4 user4 pass4
5 user5 pass5
8
3 6
1 2 4 5 7
21/129
2016
索引數據結構 : B+tree 索引
目的:尋找【欄位一為 5 的資料】
優點:全表掃描不需遍歷樹
資料表:
1 user1 pass1
2 user2 pass2
3 user3 pass3
4 user4 pass4
5 user5 pass5
13
4 7
1 2 3 4 5 6 7
22/129
2016
索引數據結構 : B+tree 索引
目的:尋找【欄位一為 5 的資料】
操作: 4 , O(logbn)
優點:全表掃描不需遍歷樹
資料表:
1 user1 pass1
2 user2 pass2
3 user3 pass3
4 user4 pass4
5 user5 pass5
13
4 7
1 2 3 4 5 6 7
13
b
2016
23/129
問題 2: B+tree
Q: 哪些資料庫索引數據結構支援 B+tree ?
MySQL
Oracle
Microsoft SQL Server
PostgreSQL
MongoDB
CouchDB
LevelDB
RocksDB
HBase
Cassandra
Riak
NessDB
BoltDB
TokuDB
Aerospike
Couchbase
24/129
2016
問題 2: B+tree
Q: 哪些資料庫索引數據結構支援 B+tree ?
MySQL
Oracle
Microsoft SQL Server
PostgreSQL
MongoDB
CouchDB
LevelDB
RocksDB
HBase
Cassandra
Riak
NessDB
BoltDB
TokuDB
Aerospike
Couchbase
2016
25/129
索引頁分裂
26/129
2016
索引頁分裂
觸發:頁剩餘空間 - 保留空間 < 新增資料
問題:頁分裂時會 Latch( 小鎖 )
page
page page
latch
page
27/129
2016
索引頁分裂 : 循序式新增資料
操作:新增 25( 假設頁只能存三筆資料 )
9 18
21 24
19 20 21 22 23 24
25
p1
p10
p12p11
9 18
21 24 25
19 20 21 22 23 24
p1
p10
p12p11
25
p13
latch
latch
hotspot
28/129
2016
索引頁分裂 : 亂序式新增資料
操作:新增 5( 假設頁只能存三筆資料 )
20
6 12
2 4 6 8 10 12
5
20
4 6 12
2 4 5 6 8 10 12
p1 p1
p2 p2
p4p3 p3 p4p5
latch
fragmentation fragmentation
29/129
2016
索引頁分裂 : 亂序式新增資料
Ref: http://blogs.catapultsystems.com/rnewkirk/archive/2013/05/14/sql-fragmentation-explained/
30/129
2016
索引頁分裂 : I/O 與 Page Size
資料庫 I/O 以 Page 為單位。
儲存引擎的 Page Size :
➊ PostgreSQL 8KB
➋ MySQL/InnoDB 16KB(default)
➌ MongoDB/MMAPv1 dynamic (powered by 2)
➍ MongoDB/WiredTiger 32KB(default)
➎ Percona/TokuDB 64KB(default)
31/129
2016
索引頁分裂 : 循序式新增 I/O
9 18
21 24 25
19 20 21 22 23 24
25
p1
p10
p12p11
25
p13
latch
latch
Block N+1 Block N+2 Block N+3 p11 p12 p13p10
I/O
hotspot?
hotspot
32/129
2016
索引頁分裂 : 循序式新增 I/O
如果 Page Size 比較大?
Block N+1 Block N+2 Block N+3 p11 p12 p13p10
I/O
Block N+1 Block N+2 p13p12p11p10
I/OI/O
33/129
2016
索引頁分裂 : 亂序式新增 I/O
Block N+3 Block N+4
I/O
p2 p3 p4p1 # # #p5
20
6 12
2 4 6 8 10 12
20
4 6 12
2 4 5 6 8 10 12
p1 p1
p2 p2
p4p3 p3 p4p5
latch
I/O
5
34/129
2016
索引頁分裂 : 亂序式新增 I/O
如果 Page Size 比較大?
Block N+4p4p3p2p1
I/OI/O
Block N+3 Block N+4
I/O
p2 p3 p4p1 # # #p5
I/O
#p5
I/O
2016
35/129
索引子頁結構
36/129
2016
索引子頁結構 : Non-clustered index
以 B+tree 為例
特色:子頁不包括資料本身 ( 指針指向資料 )
補充:對應的資料表稱 Heap table
資料表:循序式
1 user1 pass1
2 user2 pass2
3 user3 pass3
4 user4 pass4
5 user5 pass5
13
4 7
1 2 3 4 5 6 7
37/129
2016
索引子頁結構 : Non-clustered index
如果不是《循序式》而是《亂序式》。
資料表:亂序式
1 user1 pass1
4 user4 pass4
5 user5 pass5
2 user2 pass2
3 user3 pass3
13
4 7
1 2 3 4 5 6 7
38/129
2016
索引子頁結構 : Clustered index
以 B+tree 為例
特色:子頁包括資料本身 ( 不需指針指向資料 )
補充:對應的資料表稱 Index Organized Table(IOT)
資料表:循序式與亂序式都一樣
13
4 7
1 2 3 4 5 6 7
1 user1 pass1
2 user2 pass2
3 user3 pass3
4 user4 pass4
5 user5 pass5
39/129
2016
Non-clustered index(Heap table)
循序式
➀ 有索引指針指向資料的額外開銷。
➁ Hotspot 發生在樹最右下的頁,但循序寫及合併寫機率高。
➂ Range scan 讀取時開銷大。
亂序式
➀ 有索引指針指向資料的額外開銷。
➁ Range scan 讀取時開銷可能比循序式更大。
➂ 大量新增資料,幾乎是隨機寫,也難以合併寫。
索引子頁結構 : Non-clustered index
40/129
2016
索引子頁結構 : Clustered index
Clustered index(IOT)
循序式
➀ 資料佔頁空間,頁存放的資料量少,頁分裂頻繁。
➁ 搜尋至頁索引時,因包括資料本身,無額外指針開銷。
➂ Hotspot 發生在樹最右下的頁,但循序寫及合併寫機率高。
亂序式
➀ 資料佔頁空間,頁存放的資料量少,頁分裂頻繁。
➁ 搜尋至頁索引時,因包括資料本身,無額外指針開銷。
➂ 為了維持循序,發生大量的頁分裂。
41/129
2016
索引子頁結構 : Clustered index
Q: 循序式 / 亂序式 vs. I/O Scheduler vs. Filesystem vs. HDD / Flash / Fusion IO ?
循序式
亂序式
CFQ
Deadline
NOOP
HDD
Flash
Fusion IO
Ext4
XFS
ZFS
BtrFS
2016
42/129
Range scan
43/129
2016
Range scan
>, <, >=, <=
BETWEEN, IN
GROUP BY with max, min, count
44/129
2016
Range scan: Heap table w/ 循序式
SELECT * FROM x WHERE y BETWEEN 1 AND 7;
1 user1 pass1
2 user2 pass2
3 user3 pass3
4 user4 pass4
5 user5 pass5
6 user6 pass6
7 user7 pass7
13
4 7
1 2 3 4 5 6 7
Block N+3 ...
p1
p3
I/O
p2
p1 p2 p3 p4
I/O
Block N+M
45/129
2016
Range scan: Heap table w/ 亂序式
SELECT * FROM x WHERE y BETWEEN 1 AND 7;
1 user1 pass1
4 user4 pass4
5 user5 pass5
2 user2 pass2
3 user3 pass3
7 user7 pass7
6 user6 pass6
13
4 7
1 2 3 4 5 6 7
I/O
p5 p7 p3 p6
I/O I/OI/O
p1 # p2 p4...
p4
p7
p5
p1
p3
p2
p6
46/129
2016
Range scan: Heap table w/ 亂序式
I/O
p5 p7 p3 p6
I/O I/OI/O
p1 # p2 p4...
Ref: http://etutorials.org/SQL/Postgresql/Part+I+General+PostgreSQL+Use/Chapter+4.+Performance/Gathering+Performance+Information/
47/129
2016
Range scan: IOT w/ 循序式 & 亂序式
SELECT * FROM x WHERE y BETWEEN 1 AND 7;
13
4 7
1 2 3 4 5 6 7
1 user1 pass1
2 user2 pass2
3 user3 pass3
4 user4 pass4
5 user5 pass5
6 user6 pass6
7 user7 pass7
p1
p3
p2
Block N+3 ...
I/O
p1 p2 p3 p4
I/O
Block N+M
2016
48/129
問題 3
Q: 哪些資料庫支援 Heap table ?哪些支援 IOT ?
MySQL
Oracle
Microsoft SQL Server
PostgreSQL
MongoDB
CouchDB
49/129
2016
問題 3
Heap table IOT
MySQL/MyISAM O X
MySQL/InnoDB X O
Oracle O O
Microsoft SQL Server O O
PostgreSQL O X
MongoDB/MMAPv1 O X
MongoDB/WiredTiger O X
CouchDB X O
50/129
2016
問題 3
Q: 選什麼資料庫比較好?
是個偽命題,需視你的場景而定。
2016
51/129
特別篇 1: MySQL 生態系
Q: MySQL 生態系, MySQL / Percona / MariaDB /
WebScaleSQL 該怎麼選擇?
52/129
2016
特別篇 1: MySQL 生態系
MySQL
➀ 官方,有 Oracle 技術支持及專利保護。
➁ 最新的 MySQL 5.7 擁有大量新特性。
➂ 商業因素預設不會接受其他分支的特性。
Percona
➀ drop-in compatible with (official) MySQL 。
➁ 針對 MySQL 額外新增許多特性。
➂ 額外支援 XtraDB / TokuDB 等引擎。
➃ 商業特性可接受其他所有分支的特性。
53/129
2016
特別篇 1: MySQL 生態系
MariaDB
➀ drop-in replacement for (official) MySQL 。
➁ MariaDB 10 基於 MySQL 5.6 ,但不相容 5.7 。
➂ 額外支援 XtraDB / TokuDB / Cassandra / CONNECT 等引擎。
➃ 至今仍沒有穩定的自我開發儲存引擎。
XtraDB / TokuDB 都屬 Percona 公司。
WebScaleSQL
➀ 基於 5.6 ,但可收納 5.7 特性。
➁ 專針對特大型 Web 公司需求而生,小心駕馭。
54/129
2016
特別篇 1: MySQL 生態系
MySQL 5.7 解決了 index→lock contention 問題。
2016
55/129
特別篇 2: PostgreSQL
PostgreSQL 是 Object-relational database
56/129
2016
特別篇 2: PostgreSQL (Fusion IO)
Fusion IO 可大幅排除 IO Bottlenect 的可能性。
57/129
2016
特別篇 2: PostgreSQL (Fusion IO)
Fusion IO 只特別支援 Oracle / MySQL / Percona / MariaDB ?
Ref: https://www.sandisk.com/business/datacenter/resources/overviews/accelerate-mysql-open-source-databases
58/129
2016
特別篇 2: PostgreSQL (Fusion IO)
Fusion IO 可讓 MySQL 免除 double write 。
Ref: https://www.sandisk.com/business/datacenter/resources/overviews/accelerate-mysql-open-source-databases
59/129
2016
特別篇 2: PostgreSQL (Fragmentation)
PostgreSQL(HOT) 天性無法避免 fragmentation 。
Ref: http://etutorials.org/SQL/Postgresql/Part+I+General+PostgreSQL+Use/Chapter+4.+Performance/Gathering+Performance+Information/
60/129
2016
特別篇 2: PostgreSQL (Index Bloat)
PostgreSQL(non HOT updates) 天性無法避免 index bloat 。
Ref: PostgreSQL 9.0 High Performance [PACKT] (2010) (p171)
61/129
2016
特別篇 2: PostgreSQL (Index Bloat)
62/129
2016
特別篇 2: PostgreSQL (Index Bloat)
63/129
2016
特別篇 2: PostgreSQL (Merge IO)
PostgreSQL 沒有類似 MySQL 的 Change Buffer 。
Ref: http://www.slideshare.net/morgo/inno-db-presentation (p9)
64/129
2016
特別篇 2: PostgreSQL (Merge IO)
MySQL Insert Buffering( 現在改名 Change Buffer) :
1. Reducing the number of disk i/o operations by merging i/o
requests to the same block.
2. Some random i/o operations can be sequential.
Ref: http://www.percona.com/files/presentations/percona-live/london-2011/PLUK2011-linux-and-hw-optimizations-for-mysql.pdf (p17)
65/129
2016
特別篇 2: PostgreSQL (Merge IO)
66/129
2016
特別篇 2: PostgreSQL ( 儲存引擎 )
Microsoft SQL Server / Oracle 支援 Heap table 及 IOT ,
可依各資料表的特性分別採用。
MySQL 及 MongoDB 支援可抽換儲存引擎,也可依資料表的
特性分別採用。
但 PostgreSQL 只有一個儲存引擎,也只支援 Heap table 。
2016
67/129
特別篇 3: MongoDB
68/129
2016
特別篇 3: MongoDB
Ref: http://itindex.net/detail/43573
69/129
2016
特別篇 3: MongoDB
Ref: http://sql-vs-nosql.blogspot.tw/2013/11/indexes-comparison-mongodb-vs-mssqlserver.html
70/129
2016
特別篇 3: MongoDB
Ref: http://learnmongodbthehardway.com/schema/chapter4/
B+Tree / Heap Table
71/129
2016
特別篇 3: MongoDB
Ref: Indexing and Performance Tuning (2015-11-03).pdf (p39)
72/129
2016
特別篇 3: MongoDB
Index
➀ ”統一命名為 _id”
➁ ”新增若未指定 _id” 值,會使用 ObjectId
➂ ObjectId 為 12-byte BSON 型態
➊ 4-byte 為 UNIX 紀元時間
➋ 3-byte 為機器識別碼
➌ 2-byte 為 Process ID
➍ 3-byte 為隨機值
Ref: https://docs.mongodb.org/manual/reference/object-id/
“_id” : ObjectId(“563479cc8a8a4246bd27d784”)
“_id” : ObjectId(“563479d48a8a4246bd27d785”)
“_id” : ObjectId(“563479df8a8a4246bd27d786”)
循序式 UUID
73/129
2016
特別篇 3: MongoDB
MMAPv1 儲存引擎
➀ Memory-mapped files
Ref: http://learnmongodbthehardway.com/schema/chapter3/
74/129
2016
特別篇 3: MongoDB
MMAPv1 儲存引擎
➀ Memory-mapped files
➁ Padding
Ref: http://learnmongodbthehardway.com/schema/chapter3/
75/129
2016
特別篇 3: MongoDB
MMAPv1 儲存引擎
➀ Memory-mapped files
➁ Padding
➂ Fragmentation
Ref: http://learnmongodbthehardway.com/schema/chapter3/
76/129
2016
特別篇 3: MongoDB
MMAPv1 儲存引擎
➀ Memory-mapped files
➁ Padding
➂ Fragmentation
➃ Collection-level locking (WiredTiger 為 Document-level)
Ref: http://sql-vs-nosql.blogspot.tw/2013/11/indexes-comparison-mongodb-vs-mssqlserver.html
77/129
2016
特別篇 3: MongoDB
MMAPv1 儲存引擎
➀ Memory-mapped files
➁ Padding
➂ Fragmentation
➃ Collection-level locking (WiredTiger 為 Document-level)
➄ MongoDB 3.2 以前為預設引擎, 3.2 後換 WiredTiger
Ref: https://docs.mongodb.org/manual/core/wiredtiger/
78/129
2016
特別篇 3: MongoDB
MMAPv1 的 Fragmentation 問題
Ref: http://www.slideshare.net/mongodb/7-managing-a-maturing-mongo-db-ecosystem-charity-majors (p35)
左邊是大量 Fragmentation ;
右邊是修復 Fragmentation 後
79/129
2016
特別篇 3: MongoDB
MMAPv1 的 Fragmentation 問題
動作:連續新增 5 個 Document
Collection :
{Document 1}
{Document 2}
{Document 3}
{Document 4}
{Document 5}
80/129
2016
特別篇 3: MongoDB
MMAPv1 的 Fragmentation 問題
動作:更新 Document 3
情況一:新的 Document 3 大小 <= 原先大小
Collection :
{Document 1}
{Document 2}
{Document 3}
{Document 4}
{Document 5}
{Document 1}
{Document 2}
{Document 3‘}
{Document 4}
{Document 5}
81/129
2016
特別篇 3: MongoDB
MMAPv1 的 Fragmentation 問題
動作:更新 Document 3
情況二:新的 Document 3 大小 > 原先大小
Collection :
{Document 1}
{Document 2}
{Document 3}
{Document 4}
{Document 5}
{Document 1}
{Document 2}
Free
{Document 4}
{Document 5}
{Document 3‘}
82/129
2016
特別篇 3: MongoDB
MMAPv1 的 Fragmentation 問題
動作:新增 Document 6
Collection :
{Document 1}
{Document 2}
Free
{Document 4}
{Document 5}
{Document 3‘}
83/129
2016
特別篇 3: MongoDB
MMAPv1 的 Fragmentation 問題
動作:新增 Document 6
情況一: Document 6 大小 <= 原先 Document 3 (Free) 大小
Collection :
{Document 1}
{Document 2}
{Document 6}
{Document 4}
{Document 5}
{Document 3‘}
{Document 1}
{Document 2}
Free
{Document 4}
{Document 5}
{Document 3‘}
84/129
2016
特別篇 3: MongoDB
MMAPv1 的 Fragmentation 問題
動作:新增 Document 6
情況二: Document 6 大小 > 原先 Document 3 (Free) 大小
Collection :
{Document 1}
{Document 2}
Free
{Document 4}
{Document 5}
{Document 3‘}
{Document 6}
{Document 1}
{Document 2}
Free
{Document 4}
{Document 5}
{Document 3‘}
85/129
2016
特別篇 3: MongoDB
特色與改善
➀ Sharding/Replica 較容易
( 但 Sharding/Replica 只有 Primary 可寫 )
➁ Dynamic schema ( 不是 Schemaless)
➂ 儲存引擎可抽換
➊ MMAPv1
➋ WiredTiger
➌ inMemory
➍ Devnull
➎ (RocksDB)
86/129
2016
特別篇 3: MongoDB
特色與改善
➃ 寫入的 Locking level 改善
2.2 版前, Process-level lock ,一個 Mongod 實例一個鎖
2.8 版前, Database-level lock ,一個 DB 一個鎖
2.8 版之後, WiredTiger 提供 Document-level lock
3.0 版之後, MMAPv1 改為 Collection-level lock
Ref: http://sql-vs-nosql.blogspot.tw/2013/11/indexes-comparison-mongodb-vs-mssqlserver.html
87/129
2016
特別篇 3: MongoDB
特色與改善
➄ 支援 MapReduce
2.4 版前,使用 SpiderMonkey ,是 single threaded
2.4 版之後,改用 V8 engine ,改善問題
➅ Single thread model ,大多時候只用到一顆 CPU
(WiredTiger 已支援 Multiple CPUs)
2016
88/129
特別篇 4: RDMBS or NoSQL ?
Q: 使用 RDBMS 還是 NoSQL ?
89/129
2016
特別篇 4: RDMBS or NoSQL ?
Q: 使用 RDBMS 還是 NoSQL ?
是個偽命題,需視你的場景而定。
90/129
2016
特別篇 4: RDMBS or NoSQL ?
不過 RDBMS 及 NoSQL 的分界會愈來愈小。
過去的一些 RDBMS 已開始支援 NoSQL 特性,
Microsoft SQL Server / Oracle / MySQL /
PostgreSQL 都確定支援 JSON(B) 操作。
Percona / MariaDB 可抽換為 TokuDB 引擎,
MariaDB 更可抽換為 Cassandra 引擎。
NoSQL 等也開始支援強一致性。
91/129
2016
特別篇 4: RDMBS or NoSQL ?
不過 RDBMS 及 NoSQL 的分界會愈來愈小。
過去的一些 RDBMS 已開始支援 NoSQL 特性,
Microsoft SQL Server / Oracle / MySQL /
PostgreSQL 都確定支援 JSON(B) 操作。
Percona / MariaDB 可抽換為 TokuDB 引擎,
MariaDB 更可抽換為 Cassandra 引擎。
NoSQL 等也開始支援強一致性。
NewSQL
2016
92/129
特別篇 5: 黑暗執行緒案例
Q: 試著分析黑暗執行緒的文章。
【 GUID Primary Key 資料庫避雷守則】
Ref: http://blog.darkthread.net/post-2016-01-29-guid-as-pk-on-db.aspx
93/129
2016
特別篇 5: 黑暗執行緒案例
以架構設計而言,我更傾向讓應用伺服器決定 GUID / UUID 的值,
理由有幾個。
➊ 未來若需要異質資料庫彼此交換資料, GUID / UUID 的衝突會
更小。例如若 SQL Server 要與 MySQL 交換, MySQL 沒有 NEWID /
NEWSEQUENTIALID 函式,所以勢必要用另一種算法來計算 UUID ,
而算法不同就可能破壞原本 GUID / UUID 不會重複的機率。
➋ 資料庫在整體架構中,是最難以擴展的,所以我傾向讓資料庫做愈少
事情愈好。 GUID / UUID 是需要計算的,即使開銷很低,但若量大還是
很可觀,所以我還是會把計算的成本移至應用伺服器處理。
94/129
2016
特別篇 5: 黑暗執行緒案例
➌ 應用伺服器脫離 SQL Server 後,就無法使用 NEWID 及
NEWSEQUENTIALID ,所以需要找 UUID 產生器。 UUID 產生器有
幾種版本, UUIDv1 是類循序性, UUIDv4 是亂序性,可以依業務
場景選擇所需。而且 UUIDv1 的類循序性不像 NEWSEQUENTIALID
這麼容易猜測。
➍ 大規模架構中,全循序性 Insert 不一定是好事。想像一下,順序性
Insert 時,所有資料會集中在樹最右下角的 Leaf Page Insert ,當
Page 滿後,就必須 Page Split ,此時就一定有 Latch 。 Latch 會減
緩 Insert 的速度。再加上實際在硬碟寫入的 Block 也會變成是 Hotspot 。
所以有時候,適當非循序性所造成的 Fragmentation 有時反而會更快。
最後有可能會變成全順序性 Insert 不一定最快,全隨機性 Insert 也不
一定最好,反而中間找平衡才是最佳的。而這時把 UUID 的計算移到應
用伺服器,剛好可以滿足這點。
95/129
2016
特別篇 5: 黑暗執行緒案例
黑暗執行緒提供的表設計建議
96/129
2016
特別篇 5: 黑暗執行緒案例
黑暗執行緒提供的表設計建議
4c.. cb.. ee..
07.. 3b.. 4c.. 5b.. 9e.. cb.. ee..
Clustered Index ( 循序式 )
Nonclustered Index ( 亂序式 )
3 6 7
1 2 3 4 5 6 7
97/129
2016
98/129
2016
特別篇 5: 黑暗執行緒案例
假設已有五筆資料
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
3 5
1 2 3 4 5
[SeqNo] [FlowId] ...
1 07.. ...
2 9e.. ...
3 3b.. ...
4 cb.. ...
5 5b.. ...
1 3 5 2 4
Nonclustered Index ( 亂序式 )
Clustered Index ( 循序式 )
99/129
2016
特別篇 5: 黑暗執行緒案例
尋找【 WHERE FlowId = “5b..” 】
IO 次數: 0
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
3 5
1 2 3 4 5
[SeqNo] [FlowId] ...
1 07.. ...
2 9e.. ...
3 3b.. ...
4 cb.. ...
5 5b.. ...
1 3 5 2 4
Nonclustered Index ( 亂序式 )
Clustered Index ( 循序式 )
100/129
2016
特別篇 5: 黑暗執行緒案例
尋找【 WHERE FlowId = “5b..” 】
IO 次數: 1
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
3 5
1 2 3 4 5
[SeqNo] [FlowId] ...
1 07.. ...
2 9e.. ...
3 3b.. ...
4 cb.. ...
5 5b.. ...
1 3 5 2 4
Nonclustered Index ( 亂序式 )
Clustered Index ( 循序式 )
101/129
2016
特別篇 5: 黑暗執行緒案例
尋找【 WHERE FlowId = “5b..” 】
IO 次數: 2
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
3 5
1 2 3 4 5
[SeqNo] [FlowId] ...
1 07.. ...
2 9e.. ...
3 3b.. ...
4 cb.. ...
5 5b.. ...
1 3 5 2 4
Nonclustered Index ( 亂序式 )
Clustered Index ( 循序式 )
102/129
2016
特別篇 5: 黑暗執行緒案例
尋找【 WHERE FlowId = “5b..” 】
IO 次數: 3
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
3 5
1 2 3 4 5
[SeqNo] [FlowId] ...
1 07.. ...
2 9e.. ...
3 3b.. ...
4 cb.. ...
5 5b.. ...
1 3 5 2 4
Nonclustered Index ( 亂序式 )
Clustered Index ( 循序式 )
103/129
2016
特別篇 5: 黑暗執行緒案例
尋找【 WHERE FlowId = “5b..” 】
IO 次數: 4 ( 完成 )
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
3 5
1 2 3 4 5
[SeqNo] [FlowId] ...
1 07.. ...
2 9e.. ...
3 3b.. ...
4 cb.. ...
5 5b.. ...
1 3 5 2 4
Nonclustered Index ( 亂序式 )
Clustered Index ( 循序式 )
104/129
2016
特別篇 5: 黑暗執行緒案例
新增【 SeqNo: 6, FlowID: 4c.. 】
IO 次數: 0
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
3 5
1 2 3 4 5
[SeqNo] [FlowId] ...
1 07.. ...
2 9e.. ...
3 3b.. ...
4 cb.. ...
5 5b.. ...
6 4c.. ...
1 3 5 2 4
Nonclustered Index ( 亂序式 )
Clustered Index ( 循序式 )
105/129
2016
特別篇 5: 黑暗執行緒案例
新增【 SeqNo: 6, FlowID: 4c.. 】
IO 次數: 1
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
3 5
1 2 3 4 5
[SeqNo] [FlowId] ...
1 07.. ...
2 9e.. ...
3 3b.. ...
4 cb.. ...
5 5b.. ...
6 4c.. ...
1 3 5 2 4
Nonclustered Index ( 亂序式 )
Clustered Index ( 循序式 )
106/129
2016
特別篇 5: 黑暗執行緒案例
新增【 SeqNo: 6, FlowID: 4c.. 】
IO 次數: 2
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
3 5
1 2 3 4 5
[SeqNo] [FlowId] ...
1 07.. ...
2 9e.. ...
3 3b.. ...
4 cb.. ...
5 5b.. ...
6 4c.. ...
1 3 5 2 4
Nonclustered Index ( 亂序式 )
Clustered Index ( 循序式 )
107/129
2016
特別篇 5: 黑暗執行緒案例
新增【 SeqNo: 6, FlowID: 4c.. 】
IO 次數: 3+3
Page Split 次數: 1
3 5
1 2 3 4 5
[SeqNo] [FlowId] ...
1 07.. ...
2 9e.. ...
3 3b.. ...
4 cb.. ...
5 5b.. ...
6 4c.. ...
Nonclustered Index ( 亂序式 )
Clustered Index ( 循序式 )
07.. 3b.. 4c.. 5b..
1 3 6 5 42
3b.. 5b.. cb..
9e.. cb..
108/129
2016
特別篇 5: 黑暗執行緒案例
新增【 SeqNo: 6, FlowID: 4c.. 】
IO 次數: 3+3+1
Page Split 次數: 1
3 5
1 2 3 4 5
[SeqNo] [FlowId] ...
1 07.. ...
2 9e.. ...
3 3b.. ...
4 cb.. ...
5 5b.. ...
6 4c.. ...
Nonclustered Index ( 亂序式 )
Clustered Index ( 循序式 )
07.. 3b.. 4c.. 5b..
1 3 6 5 42
3b.. 5b.. cb..
9e.. cb..
109/129
2016
特別篇 5: 黑暗執行緒案例
新增【 SeqNo: 6, FlowID: 4c.. 】
IO 次數: 3+3+2
Page Split 次數: 1
3 5
1 2 3 4 5
[SeqNo] [FlowId] ...
1 07.. ...
2 9e.. ...
3 3b.. ...
4 cb.. ...
5 5b.. ...
6 4c.. ...
Nonclustered Index ( 亂序式 )
Clustered Index ( 循序式 )
07.. 3b.. 4c.. 5b..
1 3 6 5 42
3b.. 5b.. cb..
9e.. cb..
110/129
2016
特別篇 5: 黑暗執行緒案例
新增【 SeqNo: 6, FlowID: 4c.. 】
IO 次數: 3+3+3
Page Split 次數: 1
3 5
1 2 3 4 5 6
[SeqNo] [FlowId] ...
1 07.. ...
2 9e.. ...
3 3b.. ...
4 cb.. ...
5 5b.. ...
6 4c.. ...
Nonclustered Index ( 亂序式 )
Clustered Index ( 循序式 )
07.. 3b.. 4c.. 5b..
1 3 6 5 42
3b.. 5b.. cb..
9e.. cb..
111/129
2016
特別篇 5: 黑暗執行緒案例
新增【 SeqNo: 6, FlowID: 4c.. 】
IO 次數: 3+3+4=10 ( 完成 )
Page Split 次數: 1
07.. 3b.. 4c.. 5b..
3 6
1 2 3 4 5 6
[SeqNo] [FlowId] ...
1 07.. ...
2 9e.. ...
3 3b.. ...
4 cb.. ...
5 5b.. ...
6 4c.. ...
1 3 6 5 42
Nonclustered Index ( 亂序式 )
Clustered Index ( 循序式 )
3b.. 5b.. cb..
9e.. cb..
112/129
2016
特別篇 5: 黑暗執行緒案例
如果用一般亂序式 UUID
[FlowId] ... ...
07.. ... ...
9e.. ... ...
3b.. ... ...
cb.. ... ...
5b.. ... ...
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
Clustered Index ( 亂序式 )
113/129
2016
特別篇 5: 黑暗執行緒案例
尋找【 WHERE FlowId = “5b..” 】
IO 次數: 0
[FlowId] ... ...
07.. ... ...
9e.. ... ...
3b.. ... ...
cb.. ... ...
5b.. ... ...
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
Clustered Index ( 亂序式 )
114/129
2016
特別篇 5: 黑暗執行緒案例
尋找【 WHERE FlowId = “5b..” 】
IO 次數: 1
[FlowId] ... ...
07.. ... ...
9e.. ... ...
3b.. ... ...
cb.. ... ...
5b.. ... ...
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
Clustered Index ( 亂序式 )
115/129
2016
特別篇 5: 黑暗執行緒案例
尋找【 WHERE FlowId = “5b..” 】
IO 次數: 2 ( 完成 )
[FlowId] ... ...
07.. ... ...
9e.. ... ...
3b.. ... ...
cb.. ... ...
5b.. ... ...
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
Clustered Index ( 亂序式 )
116/129
2016
特別篇 5: 黑暗執行緒案例
新增【 FlowID: 4c.. 】
IO 次數: 0
[FlowId] ... ...
07.. ... ...
9e.. ... ...
3b.. ... ...
cb.. ... ...
5b.. ... ...
4c.. ... ...
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
Clustered Index ( 亂序式 )
117/129
2016
特別篇 5: 黑暗執行緒案例
新增【 FlowID: 4c.. 】
IO 次數: 1
[FlowId] ... ...
07.. ... ...
9e.. ... ...
3b.. ... ...
cb.. ... ...
5b.. ... ...
4c.. ... ...
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
Clustered Index ( 亂序式 )
118/129
2016
特別篇 5: 黑暗執行緒案例
新增【 FlowID: 4c.. 】
IO 次數: 2
[FlowId] ... ...
07.. ... ...
9e.. ... ...
3b.. ... ...
cb.. ... ...
5b.. ... ...
4c.. ... ...
5b.. cb..
07.. 3b.. 5b.. 9e.. cb..
Clustered Index ( 亂序式 )
119/129
2016
特別篇 5: 黑暗執行緒案例
新增【 FlowID: 4c.. 】
IO 次數: 3+3 ( 完成 )
Page Split 次數: 1
[FlowId] ... ...
07.. ... ...
9e.. ... ...
3b.. ... ...
cb.. ... ...
5b.. ... ...
4c.. ... ...
3b.. 5b.. cb..
07.. 3b.. 4c.. 5b..
Clustered Index ( 亂序式 )
9e.. cb..
120/129
2016
特別篇 5: 黑暗執行緒案例
如果用一般循序式 UUID
[FlowId] ... ...
1 ... ...
2 ... ...
3 ... ...
4 ... ...
5 ... ...
3 5
1 2 3 4 5
Clustered Index ( 循序式 )
121/129
2016
特別篇 5: 黑暗執行緒案例
尋找【 WHERE FlowId = 5 】
IO 次數: 0
[FlowId] ... ...
1 ... ...
2 ... ...
3 ... ...
4 ... ...
5 ... ...
3 5
1 2 3 4 5
Clustered Index ( 循序式 )
122/129
2016
特別篇 5: 黑暗執行緒案例
尋找【 WHERE FlowId = 5 】
IO 次數: 1
[FlowId] ... ...
1 ... ...
2 ... ...
3 ... ...
4 ... ...
5 ... ...
3 5
1 2 3 4 5
Clustered Index ( 循序式 )
123/129
2016
特別篇 5: 黑暗執行緒案例
尋找【 WHERE FlowId = 5 】
IO 次數: 2 ( 完成 )
[FlowId] ... ...
1 ... ...
2 ... ...
3 ... ...
4 ... ...
5 ... ...
3 5
1 2 3 4 5
Clustered Index ( 循序式 )
124/129
2016
特別篇 5: 黑暗執行緒案例
新增【 FlowID: 6 】
IO 次數: 0
[FlowId] ... ...
1 ... ...
2 ... ...
3 ... ...
4 ... ...
5 ... ...
6 ... ...
3 5
1 2 3 4 5
Clustered Index ( 循序式 )
125/129
2016
特別篇 5: 黑暗執行緒案例
新增【 FlowID: 6 】
IO 次數: 1
[FlowId] ... ...
1 ... ...
2 ... ...
3 ... ...
4 ... ...
5 ... ...
6 ... ...
3 5
1 2 3 4 5
Clustered Index ( 循序式 )
126/129
2016
特別篇 5: 黑暗執行緒案例
新增【 FlowID: 6 】
IO 次數: 2
[FlowId] ... ...
1 ... ...
2 ... ...
3 ... ...
4 ... ...
5 ... ...
6 ... ...
3 5
1 2 3 4 5
Clustered Index ( 循序式 )
127/129
2016
特別篇 5: 黑暗執行緒案例
新增【 FlowID: 6 】
IO 次數: 3+1 ( 完成 )
[FlowId] ... ...
1 ... ...
2 ... ...
3 ... ...
4 ... ...
5 ... ...
6 ... ...
3 6
1 2 3 4 5 6
Clustered Index ( 循序式 )
128/129
2016
特別篇 5: 黑暗執行緒案例
小結:本場景為例
黑暗執行緒 亂序式 UUID 循序式 UUID
Point-of-query IO 4 2 2
Insert IO 10 6 4
Insert
(Page Split)
1 1 0
Space size ++ + +
Latch(%) ++ + +
129/129
2016
特別篇 6: MultiColumn B-Tree Index
[Col#1] [Col#2]
1 A
3 B
3 C
4 D
3 C
CREATE INDEX ON table (Col#1, Col#2);
1 A 3 B 3 C 4 D

More Related Content

What's hot

What's hot (20)

Linux and H/W optimizations for MySQL
Linux and H/W optimizations for MySQLLinux and H/W optimizations for MySQL
Linux and H/W optimizations for MySQL
 
分散システムの限界について知ろう
分散システムの限界について知ろう分散システムの限界について知ろう
分散システムの限界について知ろう
 
VirtualBox と Rocky Linux 8 で始める Pacemaker ~ VirtualBox でも STONITH 機能が試せる! Vi...
VirtualBox と Rocky Linux 8 で始める Pacemaker  ~ VirtualBox でも STONITH 機能が試せる! Vi...VirtualBox と Rocky Linux 8 で始める Pacemaker  ~ VirtualBox でも STONITH 機能が試せる! Vi...
VirtualBox と Rocky Linux 8 で始める Pacemaker ~ VirtualBox でも STONITH 機能が試せる! Vi...
 
最新機能までを総ざらい!PostgreSQLの注目機能を振り返る(第32回 中国地方DB勉強会 in 岡山 発表資料)
最新機能までを総ざらい!PostgreSQLの注目機能を振り返る(第32回 中国地方DB勉強会 in 岡山 発表資料)最新機能までを総ざらい!PostgreSQLの注目機能を振り返る(第32回 中国地方DB勉強会 in 岡山 発表資料)
最新機能までを総ざらい!PostgreSQLの注目機能を振り返る(第32回 中国地方DB勉強会 in 岡山 発表資料)
 
MyRocks Deep Dive
MyRocks Deep DiveMyRocks Deep Dive
MyRocks Deep Dive
 
Wait! What’s going on inside my database?
Wait! What’s going on inside my database?Wait! What’s going on inside my database?
Wait! What’s going on inside my database?
 
MySQL Replication Performance Tuning for Fun and Profit!
MySQL Replication Performance Tuning for Fun and Profit!MySQL Replication Performance Tuning for Fun and Profit!
MySQL Replication Performance Tuning for Fun and Profit!
 
スケールアップファーストのNoSQL、ScyllaDB(スキュラDB)
スケールアップファーストのNoSQL、ScyllaDB(スキュラDB)スケールアップファーストのNoSQL、ScyllaDB(スキュラDB)
スケールアップファーストのNoSQL、ScyllaDB(スキュラDB)
 
PostgreSQL: XID周回問題に潜む別の問題
PostgreSQL: XID周回問題に潜む別の問題PostgreSQL: XID周回問題に潜む別の問題
PostgreSQL: XID周回問題に潜む別の問題
 
RISC-Vの可能性
RISC-Vの可能性RISC-Vの可能性
RISC-Vの可能性
 
Memoizeの仕組み(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)
Memoizeの仕組み(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)Memoizeの仕組み(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)
Memoizeの仕組み(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)
オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)
オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
iostat await svctm の 見かた、考え方
iostat await svctm の 見かた、考え方iostat await svctm の 見かた、考え方
iostat await svctm の 見かた、考え方
 
NAND Flash から InnoDB にかけての話(仮)
NAND Flash から InnoDB にかけての話(仮)NAND Flash から InnoDB にかけての話(仮)
NAND Flash から InnoDB にかけての話(仮)
 
Solving PostgreSQL wicked problems
Solving PostgreSQL wicked problemsSolving PostgreSQL wicked problems
Solving PostgreSQL wicked problems
 
HDFS vs. MapR Filesystem
HDFS vs. MapR FilesystemHDFS vs. MapR Filesystem
HDFS vs. MapR Filesystem
 
不揮発メモリ(NVDIMM)とLinuxの対応動向について
不揮発メモリ(NVDIMM)とLinuxの対応動向について不揮発メモリ(NVDIMM)とLinuxの対応動向について
不揮発メモリ(NVDIMM)とLinuxの対応動向について
 
Magnum IO GPUDirect Storage 最新情報
Magnum IO GPUDirect Storage 最新情報Magnum IO GPUDirect Storage 最新情報
Magnum IO GPUDirect Storage 最新情報
 
Hokkaido.cap#1 Wiresharkの使い方(基礎編)
Hokkaido.cap#1 Wiresharkの使い方(基礎編)Hokkaido.cap#1 Wiresharkの使い方(基礎編)
Hokkaido.cap#1 Wiresharkの使い方(基礎編)
 
MySQLerの7つ道具 plus
MySQLerの7つ道具 plusMySQLerの7つ道具 plus
MySQLerの7つ道具 plus
 

Similar to 資料庫索引數據結構及主鍵設計(b+tree)(part 1)

搜狐Pv insight(py)技术交流
搜狐Pv insight(py)技术交流搜狐Pv insight(py)技术交流
搜狐Pv insight(py)技术交流
bj
 
搜狐Pv insight(py)技术交流
搜狐Pv insight(py)技术交流搜狐Pv insight(py)技术交流
搜狐Pv insight(py)技术交流
jondynet
 
Using google appengine_1027
Using google appengine_1027Using google appengine_1027
Using google appengine_1027
Wei Sun
 
Using google appengine (2)
Using google appengine (2)Using google appengine (2)
Using google appengine (2)
Wei Sun
 
Google雲端 第一章準備篇
Google雲端 第一章準備篇Google雲端 第一章準備篇
Google雲端 第一章準備篇
gracebrainyu
 
Using google appengine_final
Using google appengine_finalUsing google appengine_final
Using google appengine_final
Wei Sun
 

Similar to 資料庫索引數據結構及主鍵設計(b+tree)(part 1) (20)

搜狐Pv insight(py)技术交流
搜狐Pv insight(py)技术交流搜狐Pv insight(py)技术交流
搜狐Pv insight(py)技术交流
 
搜狐Pv insight(py)技术交流
搜狐Pv insight(py)技术交流搜狐Pv insight(py)技术交流
搜狐Pv insight(py)技术交流
 
LinkIt 7697 開發平台簡介 (Traditional Chinese)
LinkIt 7697 開發平台簡介 (Traditional Chinese)LinkIt 7697 開發平台簡介 (Traditional Chinese)
LinkIt 7697 開發平台簡介 (Traditional Chinese)
 
Data Pipeline Matters
Data Pipeline MattersData Pipeline Matters
Data Pipeline Matters
 
Using google appengine_1027
Using google appengine_1027Using google appengine_1027
Using google appengine_1027
 
前端开发演进之路 | The development of the front end - By TaoBeier
前端开发演进之路 | The development of the front end - By TaoBeier前端开发演进之路 | The development of the front end - By TaoBeier
前端开发演进之路 | The development of the front end - By TaoBeier
 
Using google appengine (2)
Using google appengine (2)Using google appengine (2)
Using google appengine (2)
 
Coscup 2018
Coscup 2018Coscup 2018
Coscup 2018
 
Bluemix Node-Red Part II
Bluemix Node-Red Part IIBluemix Node-Red Part II
Bluemix Node-Red Part II
 
Google雲端 第一章準備篇
Google雲端 第一章準備篇Google雲端 第一章準備篇
Google雲端 第一章準備篇
 
HPX_HP25_專案管理:如何言之有物
HPX_HP25_專案管理:如何言之有物HPX_HP25_專案管理:如何言之有物
HPX_HP25_專案管理:如何言之有物
 
廣宣學堂Python金融爬蟲原理班 20170416
廣宣學堂Python金融爬蟲原理班 20170416廣宣學堂Python金融爬蟲原理班 20170416
廣宣學堂Python金融爬蟲原理班 20170416
 
程式人雜誌 -- 2014 年8月號
程式人雜誌 -- 2014 年8月號程式人雜誌 -- 2014 年8月號
程式人雜誌 -- 2014 年8月號
 
淺談物聯網巨量資料挑戰 - Jazz 王耀聰 (2016/3/17 於鴻海內湖) 免費講座
淺談物聯網巨量資料挑戰 - Jazz 王耀聰 (2016/3/17 於鴻海內湖) 免費講座淺談物聯網巨量資料挑戰 - Jazz 王耀聰 (2016/3/17 於鴻海內湖) 免費講座
淺談物聯網巨量資料挑戰 - Jazz 王耀聰 (2016/3/17 於鴻海內湖) 免費講座
 
程式人雜誌 -- 2013年4月號
程式人雜誌 -- 2013年4月號程式人雜誌 -- 2013年4月號
程式人雜誌 -- 2013年4月號
 
Using google appengine_final
Using google appengine_finalUsing google appengine_final
Using google appengine_final
 
asker's Gartner ITxpo
asker's Gartner ITxpoasker's Gartner ITxpo
asker's Gartner ITxpo
 
Bluemix Node-Red Part I
Bluemix Node-Red Part IBluemix Node-Red Part I
Bluemix Node-Red Part I
 
Deep learning hardware architecture and software deploy with docker
Deep learning hardware architecture and software deploy with dockerDeep learning hardware architecture and software deploy with docker
Deep learning hardware architecture and software deploy with docker
 
開放源碼的ASP.NET Core & ADO.NET (for VS2015)
開放源碼的ASP.NET Core & ADO.NET (for VS2015)開放源碼的ASP.NET Core & ADO.NET (for VS2015)
開放源碼的ASP.NET Core & ADO.NET (for VS2015)
 

More from Yi-Feng Tzeng

More from Yi-Feng Tzeng (20)

重新想像:如何做技術選型決策 / Rethinking : Technical Decision
重新想像:如何做技術選型決策 / Rethinking : Technical Decision重新想像:如何做技術選型決策 / Rethinking : Technical Decision
重新想像:如何做技術選型決策 / Rethinking : Technical Decision
 
擁抱開源:企業應如何善用開源技術,才能得其利而防其弊-加強版
擁抱開源:企業應如何善用開源技術,才能得其利而防其弊-加強版擁抱開源:企業應如何善用開源技術,才能得其利而防其弊-加強版
擁抱開源:企業應如何善用開源技術,才能得其利而防其弊-加強版
 
Testing in Production, Deploy on Fridays
Testing in Production, Deploy on FridaysTesting in Production, Deploy on Fridays
Testing in Production, Deploy on Fridays
 
COSCUP 2020 Day 2 - Opening Keynote
COSCUP 2020 Day 2 - Opening KeynoteCOSCUP 2020 Day 2 - Opening Keynote
COSCUP 2020 Day 2 - Opening Keynote
 
COSCUP 2020 Day 1 - Opening Keynote
COSCUP 2020 Day 1 - Opening KeynoteCOSCUP 2020 Day 1 - Opening Keynote
COSCUP 2020 Day 1 - Opening Keynote
 
Severless PHP Case : Agile Dashboard via GitLab Board API
Severless PHP Case : Agile Dashboard via GitLab Board APISeverless PHP Case : Agile Dashboard via GitLab Board API
Severless PHP Case : Agile Dashboard via GitLab Board API
 
給資安工程師開源授權觀念
給資安工程師開源授權觀念給資安工程師開源授權觀念
給資安工程師開源授權觀念
 
Progressive Deployment & NoDeploy
Progressive Deployment & NoDeployProgressive Deployment & NoDeploy
Progressive Deployment & NoDeploy
 
Dev(Sec)Ops - Architecture for Security and Compliance
Dev(Sec)Ops - Architecture for Security and ComplianceDev(Sec)Ops - Architecture for Security and Compliance
Dev(Sec)Ops - Architecture for Security and Compliance
 
擁抱開源:企業應如何善用開源技術,才能得其利而防其弊
擁抱開源:企業應如何善用開源技術,才能得其利而防其弊擁抱開源:企業應如何善用開源技術,才能得其利而防其弊
擁抱開源:企業應如何善用開源技術,才能得其利而防其弊
 
淺談量子機器學習 - 當機器學習遇見量子計算
淺談量子機器學習 - 當機器學習遇見量子計算淺談量子機器學習 - 當機器學習遇見量子計算
淺談量子機器學習 - 當機器學習遇見量子計算
 
A Modern Web Architecture for (GDPR) Compliance
A Modern Web Architecture for (GDPR) ComplianceA Modern Web Architecture for (GDPR) Compliance
A Modern Web Architecture for (GDPR) Compliance
 
量子技術 (2018 03-31)
量子技術 (2018 03-31)量子技術 (2018 03-31)
量子技術 (2018 03-31)
 
Swoole Love PHP
Swoole Love PHPSwoole Love PHP
Swoole Love PHP
 
邏輯優化的灰色面:針對網頁應用的時序攻擊 (2018臺灣資安大會: 軟體安全論壇)
邏輯優化的灰色面:針對網頁應用的時序攻擊 (2018臺灣資安大會: 軟體安全論壇)邏輯優化的灰色面:針對網頁應用的時序攻擊 (2018臺灣資安大會: 軟體安全論壇)
邏輯優化的灰色面:針對網頁應用的時序攻擊 (2018臺灣資安大會: 軟體安全論壇)
 
Modern Web Architecture Design Journey
Modern Web Architecture Design JourneyModern Web Architecture Design Journey
Modern Web Architecture Design Journey
 
恰如其分的 MySQL 設計技巧 [Modern Web 2016]
恰如其分的 MySQL 設計技巧 [Modern Web 2016]恰如其分的 MySQL 設計技巧 [Modern Web 2016]
恰如其分的 MySQL 設計技巧 [Modern Web 2016]
 
軟體接案自由職業者 (Freelancer) 意想不到的風險
軟體接案自由職業者 (Freelancer) 意想不到的風險軟體接案自由職業者 (Freelancer) 意想不到的風險
軟體接案自由職業者 (Freelancer) 意想不到的風險
 
Enterprise Architecture Case in PHP (MUZIK Online)
Enterprise Architecture Case in PHP (MUZIK Online)Enterprise Architecture Case in PHP (MUZIK Online)
Enterprise Architecture Case in PHP (MUZIK Online)
 
Redis, another step on the road
Redis, another step on the roadRedis, another step on the road
Redis, another step on the road
 

資料庫索引數據結構及主鍵設計(b+tree)(part 1)

  • 1. 資料庫索引數據結構及主鍵設計 (B+Tree) Database index data structure and primary key design (part1) 2016 Ant yftzeng@gmail.com
  • 2. 2016 2/129 自我介紹 ♪ Muzik Online (www.muzikair.com) 總工程師。 ♪ Paganini+ (http://www.paganiniplus.com/) 技術長。 ♪ BELP (fb.com/belp.general) 共同創辦人。 ♪ CHROOT (www.chroot.org) 成員。 ♪ 講師經驗 PHPConf, Modern Web Taiwan, MOPCON, WebConf, COSCUP, JSDC Taiwan, DrupalCamp Taiwan, OSDC, HITCON, ... ♪ 略懂智慧財產權、資訊安全及軟體程式設計。 ♪ 『略懂諸葛』。 ♪ 沉浸於『人性』、『法律』與『科技』的三角關係中。
  • 3. 2016 3/129 問題 1: UUID ? Q: 資料庫 Primary key 使用 UUID 比較快? Serial/Auto-Increment 1 2 3 4 5 ... UUID 3a5e439b-eeb4-4074-8b23-51c2cdd35421 1bb19e6b-9c0c-475e-a7b3-f01a6b4cd496 af4c8b80-4bf5-4bf3-a4e3-a71bed920f10 e62acb5b-a393-4707-9aa5-90f79352eb4b 2e199d72-4e49-4ace-a504-419da63878f5 ...
  • 4. 4/129 2016 問題 1: UUID ? Q: 資料庫 Primary key 使用 UUID 比較快? 偽命題
  • 5. 2016 5/129 問題 1 ( 修正 ): MySQL UUID ? Q: MySQL 的 Primary key 使用 UUID 比較快? Serial/Auto-Increment 1 2 3 4 5 ... UUID 3a5e439b-eeb4-4074-8b23-51c2cdd35421 1bb19e6b-9c0c-475e-a7b3-f01a6b4cd496 af4c8b80-4bf5-4bf3-a4e3-a71bed920f10 e62acb5b-a393-4707-9aa5-90f79352eb4b 2e199d72-4e49-4ace-a504-419da63878f5 ...
  • 6. 6/129 2016 問題 1 ( 修正 ): MySQL UUID ? Q: MySQL 的 Primary key 使用 UUID 比較快? 偽命題
  • 7. 7/129 2016 問題 1 ( 修正 ): MySQL UUID ? UUID 目前公定有五種版本: ➀ Version 1 (MAC address & date-time) ➁ Version 2 (DCE Security) ➂ Version 3 (MD5 hash & namespace) ➃ Version 4 (Random) ➄ Version 5 (SHA-1 hash & namespace) Ref: https://en.wikipedia.org/wiki/Universally_unique_identifier
  • 8. 8/129 2016 問題 1 ( 修正 ): MySQL UUID ? UUID 目前公定有五種版本: ➀ Version 1 (MAC address & date-time) ➁ Version 2 (DCE Security) ➂ Version 3 (MD5 hash & namespace) ➃ Version 4 (Random) ➄ Version 5 (SHA-1 hash & namespace) Ref: https://en.wikipedia.org/wiki/Universally_unique_identifier Version 2 未在 UUID 規格中定義,少見
  • 9. 9/129 2016 問題 1 ( 修正 ): MySQL UUID ? UUID 目前公定有五種版本: ➀ Version 1 (MAC address & date-time) ➁ Version 2 (DCE Security) ➂ Version 3 (MD5 hash & namespace) ➃ Version 4 (Random) ➄ Version 5 (SHA-1 hash & namespace) Ref: https://en.wikipedia.org/wiki/Universally_unique_identifier
  • 10. 10/129 2016 問題 1 ( 修正 ): MySQL UUID ? UUID 類循序式 ( 通常後序產生的值 > 先前產生的值 ) : ➀ Version 1 (MAC address & date-time) UUID 亂序式 ( 值的大小沒有前後關係 ) : ➂ Version 3 (MD5 hash & namespace) ➃ Version 4 (Random) ➄ Version 5 (SHA-1 hash & namespace)
  • 11. 11/129 2016 問題 1 ( 修正 ): MySQL UUID ? UUIDv1 的範例: 2190718a-c7a3-61e2-aa34-024281ed9db5 2191f33e-c7a3-61e2-9b92-024281ed9db5 2192cc0a-c7a3-61e2-be4c-024281ed9db5 21939950-c7a3-61e2-9aad-024281ed9db5 21945ff2-c7a3-61e2-90fc-024281ed9db5 219525f4-c7a3-61e2-99df-024281ed9db5 Time
  • 12. 12/129 2016 問題 1 ( 修正 ): MySQL UUID ? UUIDv4 的範例: 3a5e439b-eeb4-4074-8b23-51c2cdd35421 1bb19e6b-9c0c-475e-a7b3-f01a6b4cd496 af4c8b80-4bf5-4bf3-a4e3-a71bed920f10 e62acb5b-a393-4707-9aa5-90f79352eb4b 2e199d72-4e49-4ace-a504-419da63878f5 8cf2e49f-8ae9-43f2-a84d-78cb323114a3 Time
  • 13. 13/129 2016 問題 1 ( 修正 ): MySQL UUID ? 結論: UUID 可以是類循序式,也可以是亂序式。 但《循序式》與《亂序式》的重要性為何?
  • 14. 14/129 2016 問題 1 ( 修正 ): MySQL UUID ? Ref: https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/
  • 15. 15/129 2016 問題 1 ( 修正 ): MySQL UUID ? 延伸 : GUID 與 UUID 的差異?
  • 16. 16/129 2016 問題 1 ( 修正 ): MySQL UUID ? GUID 是 Microsoft 用詞,指的其實類似於 UUID , 但實作方式不一樣。 Microsoft 對於 GUID 的實作至少有兩種: ➀ 基於 UuidCreate 的 NEWID(SQL) ; ➁ 基於 UuidCreateSequential 的 NEWSEQUENTIALID(SQL) 。 其中 NEWID 是亂序式,而 NEWSEQUENTIALID 是循序式。
  • 18. 18/129 2016 索引數據結構 : 無索引 目的:尋找【欄位一為 5 的資料】 操作: 5 , O(n) 缺點:總是需要全表掃描 資料表: 1 user1 pass1 2 user2 pass2 3 user3 pass3 4 user4 pass4 5 user5 pass5
  • 19. 19/129 2016 索引數據結構 : B-tree 索引 B-tree = Balanced tree (not Binary tree)
  • 20. 20/129 2016 索引數據結構 : B-tree 索引 目的:尋找【欄位一為 5 的資料】 操作: 4 , O(logbn) 缺點:全表掃描需要遍歷樹 資料表: 1 user1 pass1 2 user2 pass2 3 user3 pass3 4 user4 pass4 5 user5 pass5 8 3 6 1 2 4 5 7
  • 21. 21/129 2016 索引數據結構 : B+tree 索引 目的:尋找【欄位一為 5 的資料】 優點:全表掃描不需遍歷樹 資料表: 1 user1 pass1 2 user2 pass2 3 user3 pass3 4 user4 pass4 5 user5 pass5 13 4 7 1 2 3 4 5 6 7
  • 22. 22/129 2016 索引數據結構 : B+tree 索引 目的:尋找【欄位一為 5 的資料】 操作: 4 , O(logbn) 優點:全表掃描不需遍歷樹 資料表: 1 user1 pass1 2 user2 pass2 3 user3 pass3 4 user4 pass4 5 user5 pass5 13 4 7 1 2 3 4 5 6 7 13 b
  • 23. 2016 23/129 問題 2: B+tree Q: 哪些資料庫索引數據結構支援 B+tree ? MySQL Oracle Microsoft SQL Server PostgreSQL MongoDB CouchDB LevelDB RocksDB HBase Cassandra Riak NessDB BoltDB TokuDB Aerospike Couchbase
  • 24. 24/129 2016 問題 2: B+tree Q: 哪些資料庫索引數據結構支援 B+tree ? MySQL Oracle Microsoft SQL Server PostgreSQL MongoDB CouchDB LevelDB RocksDB HBase Cassandra Riak NessDB BoltDB TokuDB Aerospike Couchbase
  • 26. 26/129 2016 索引頁分裂 觸發:頁剩餘空間 - 保留空間 < 新增資料 問題:頁分裂時會 Latch( 小鎖 ) page page page latch page
  • 27. 27/129 2016 索引頁分裂 : 循序式新增資料 操作:新增 25( 假設頁只能存三筆資料 ) 9 18 21 24 19 20 21 22 23 24 25 p1 p10 p12p11 9 18 21 24 25 19 20 21 22 23 24 p1 p10 p12p11 25 p13 latch latch hotspot
  • 28. 28/129 2016 索引頁分裂 : 亂序式新增資料 操作:新增 5( 假設頁只能存三筆資料 ) 20 6 12 2 4 6 8 10 12 5 20 4 6 12 2 4 5 6 8 10 12 p1 p1 p2 p2 p4p3 p3 p4p5 latch fragmentation fragmentation
  • 29. 29/129 2016 索引頁分裂 : 亂序式新增資料 Ref: http://blogs.catapultsystems.com/rnewkirk/archive/2013/05/14/sql-fragmentation-explained/
  • 30. 30/129 2016 索引頁分裂 : I/O 與 Page Size 資料庫 I/O 以 Page 為單位。 儲存引擎的 Page Size : ➊ PostgreSQL 8KB ➋ MySQL/InnoDB 16KB(default) ➌ MongoDB/MMAPv1 dynamic (powered by 2) ➍ MongoDB/WiredTiger 32KB(default) ➎ Percona/TokuDB 64KB(default)
  • 31. 31/129 2016 索引頁分裂 : 循序式新增 I/O 9 18 21 24 25 19 20 21 22 23 24 25 p1 p10 p12p11 25 p13 latch latch Block N+1 Block N+2 Block N+3 p11 p12 p13p10 I/O hotspot? hotspot
  • 32. 32/129 2016 索引頁分裂 : 循序式新增 I/O 如果 Page Size 比較大? Block N+1 Block N+2 Block N+3 p11 p12 p13p10 I/O Block N+1 Block N+2 p13p12p11p10 I/OI/O
  • 33. 33/129 2016 索引頁分裂 : 亂序式新增 I/O Block N+3 Block N+4 I/O p2 p3 p4p1 # # #p5 20 6 12 2 4 6 8 10 12 20 4 6 12 2 4 5 6 8 10 12 p1 p1 p2 p2 p4p3 p3 p4p5 latch I/O 5
  • 34. 34/129 2016 索引頁分裂 : 亂序式新增 I/O 如果 Page Size 比較大? Block N+4p4p3p2p1 I/OI/O Block N+3 Block N+4 I/O p2 p3 p4p1 # # #p5 I/O #p5 I/O
  • 36. 36/129 2016 索引子頁結構 : Non-clustered index 以 B+tree 為例 特色:子頁不包括資料本身 ( 指針指向資料 ) 補充:對應的資料表稱 Heap table 資料表:循序式 1 user1 pass1 2 user2 pass2 3 user3 pass3 4 user4 pass4 5 user5 pass5 13 4 7 1 2 3 4 5 6 7
  • 37. 37/129 2016 索引子頁結構 : Non-clustered index 如果不是《循序式》而是《亂序式》。 資料表:亂序式 1 user1 pass1 4 user4 pass4 5 user5 pass5 2 user2 pass2 3 user3 pass3 13 4 7 1 2 3 4 5 6 7
  • 38. 38/129 2016 索引子頁結構 : Clustered index 以 B+tree 為例 特色:子頁包括資料本身 ( 不需指針指向資料 ) 補充:對應的資料表稱 Index Organized Table(IOT) 資料表:循序式與亂序式都一樣 13 4 7 1 2 3 4 5 6 7 1 user1 pass1 2 user2 pass2 3 user3 pass3 4 user4 pass4 5 user5 pass5
  • 39. 39/129 2016 Non-clustered index(Heap table) 循序式 ➀ 有索引指針指向資料的額外開銷。 ➁ Hotspot 發生在樹最右下的頁,但循序寫及合併寫機率高。 ➂ Range scan 讀取時開銷大。 亂序式 ➀ 有索引指針指向資料的額外開銷。 ➁ Range scan 讀取時開銷可能比循序式更大。 ➂ 大量新增資料,幾乎是隨機寫,也難以合併寫。 索引子頁結構 : Non-clustered index
  • 40. 40/129 2016 索引子頁結構 : Clustered index Clustered index(IOT) 循序式 ➀ 資料佔頁空間,頁存放的資料量少,頁分裂頻繁。 ➁ 搜尋至頁索引時,因包括資料本身,無額外指針開銷。 ➂ Hotspot 發生在樹最右下的頁,但循序寫及合併寫機率高。 亂序式 ➀ 資料佔頁空間,頁存放的資料量少,頁分裂頻繁。 ➁ 搜尋至頁索引時,因包括資料本身,無額外指針開銷。 ➂ 為了維持循序,發生大量的頁分裂。
  • 41. 41/129 2016 索引子頁結構 : Clustered index Q: 循序式 / 亂序式 vs. I/O Scheduler vs. Filesystem vs. HDD / Flash / Fusion IO ? 循序式 亂序式 CFQ Deadline NOOP HDD Flash Fusion IO Ext4 XFS ZFS BtrFS
  • 43. 43/129 2016 Range scan >, <, >=, <= BETWEEN, IN GROUP BY with max, min, count
  • 44. 44/129 2016 Range scan: Heap table w/ 循序式 SELECT * FROM x WHERE y BETWEEN 1 AND 7; 1 user1 pass1 2 user2 pass2 3 user3 pass3 4 user4 pass4 5 user5 pass5 6 user6 pass6 7 user7 pass7 13 4 7 1 2 3 4 5 6 7 Block N+3 ... p1 p3 I/O p2 p1 p2 p3 p4 I/O Block N+M
  • 45. 45/129 2016 Range scan: Heap table w/ 亂序式 SELECT * FROM x WHERE y BETWEEN 1 AND 7; 1 user1 pass1 4 user4 pass4 5 user5 pass5 2 user2 pass2 3 user3 pass3 7 user7 pass7 6 user6 pass6 13 4 7 1 2 3 4 5 6 7 I/O p5 p7 p3 p6 I/O I/OI/O p1 # p2 p4... p4 p7 p5 p1 p3 p2 p6
  • 46. 46/129 2016 Range scan: Heap table w/ 亂序式 I/O p5 p7 p3 p6 I/O I/OI/O p1 # p2 p4... Ref: http://etutorials.org/SQL/Postgresql/Part+I+General+PostgreSQL+Use/Chapter+4.+Performance/Gathering+Performance+Information/
  • 47. 47/129 2016 Range scan: IOT w/ 循序式 & 亂序式 SELECT * FROM x WHERE y BETWEEN 1 AND 7; 13 4 7 1 2 3 4 5 6 7 1 user1 pass1 2 user2 pass2 3 user3 pass3 4 user4 pass4 5 user5 pass5 6 user6 pass6 7 user7 pass7 p1 p3 p2 Block N+3 ... I/O p1 p2 p3 p4 I/O Block N+M
  • 48. 2016 48/129 問題 3 Q: 哪些資料庫支援 Heap table ?哪些支援 IOT ? MySQL Oracle Microsoft SQL Server PostgreSQL MongoDB CouchDB
  • 49. 49/129 2016 問題 3 Heap table IOT MySQL/MyISAM O X MySQL/InnoDB X O Oracle O O Microsoft SQL Server O O PostgreSQL O X MongoDB/MMAPv1 O X MongoDB/WiredTiger O X CouchDB X O
  • 51. 2016 51/129 特別篇 1: MySQL 生態系 Q: MySQL 生態系, MySQL / Percona / MariaDB / WebScaleSQL 該怎麼選擇?
  • 52. 52/129 2016 特別篇 1: MySQL 生態系 MySQL ➀ 官方,有 Oracle 技術支持及專利保護。 ➁ 最新的 MySQL 5.7 擁有大量新特性。 ➂ 商業因素預設不會接受其他分支的特性。 Percona ➀ drop-in compatible with (official) MySQL 。 ➁ 針對 MySQL 額外新增許多特性。 ➂ 額外支援 XtraDB / TokuDB 等引擎。 ➃ 商業特性可接受其他所有分支的特性。
  • 53. 53/129 2016 特別篇 1: MySQL 生態系 MariaDB ➀ drop-in replacement for (official) MySQL 。 ➁ MariaDB 10 基於 MySQL 5.6 ,但不相容 5.7 。 ➂ 額外支援 XtraDB / TokuDB / Cassandra / CONNECT 等引擎。 ➃ 至今仍沒有穩定的自我開發儲存引擎。 XtraDB / TokuDB 都屬 Percona 公司。 WebScaleSQL ➀ 基於 5.6 ,但可收納 5.7 特性。 ➁ 專針對特大型 Web 公司需求而生,小心駕馭。
  • 54. 54/129 2016 特別篇 1: MySQL 生態系 MySQL 5.7 解決了 index→lock contention 問題。
  • 55. 2016 55/129 特別篇 2: PostgreSQL PostgreSQL 是 Object-relational database
  • 56. 56/129 2016 特別篇 2: PostgreSQL (Fusion IO) Fusion IO 可大幅排除 IO Bottlenect 的可能性。
  • 57. 57/129 2016 特別篇 2: PostgreSQL (Fusion IO) Fusion IO 只特別支援 Oracle / MySQL / Percona / MariaDB ? Ref: https://www.sandisk.com/business/datacenter/resources/overviews/accelerate-mysql-open-source-databases
  • 58. 58/129 2016 特別篇 2: PostgreSQL (Fusion IO) Fusion IO 可讓 MySQL 免除 double write 。 Ref: https://www.sandisk.com/business/datacenter/resources/overviews/accelerate-mysql-open-source-databases
  • 59. 59/129 2016 特別篇 2: PostgreSQL (Fragmentation) PostgreSQL(HOT) 天性無法避免 fragmentation 。 Ref: http://etutorials.org/SQL/Postgresql/Part+I+General+PostgreSQL+Use/Chapter+4.+Performance/Gathering+Performance+Information/
  • 60. 60/129 2016 特別篇 2: PostgreSQL (Index Bloat) PostgreSQL(non HOT updates) 天性無法避免 index bloat 。 Ref: PostgreSQL 9.0 High Performance [PACKT] (2010) (p171)
  • 63. 63/129 2016 特別篇 2: PostgreSQL (Merge IO) PostgreSQL 沒有類似 MySQL 的 Change Buffer 。 Ref: http://www.slideshare.net/morgo/inno-db-presentation (p9)
  • 64. 64/129 2016 特別篇 2: PostgreSQL (Merge IO) MySQL Insert Buffering( 現在改名 Change Buffer) : 1. Reducing the number of disk i/o operations by merging i/o requests to the same block. 2. Some random i/o operations can be sequential. Ref: http://www.percona.com/files/presentations/percona-live/london-2011/PLUK2011-linux-and-hw-optimizations-for-mysql.pdf (p17)
  • 66. 66/129 2016 特別篇 2: PostgreSQL ( 儲存引擎 ) Microsoft SQL Server / Oracle 支援 Heap table 及 IOT , 可依各資料表的特性分別採用。 MySQL 及 MongoDB 支援可抽換儲存引擎,也可依資料表的 特性分別採用。 但 PostgreSQL 只有一個儲存引擎,也只支援 Heap table 。
  • 68. 68/129 2016 特別篇 3: MongoDB Ref: http://itindex.net/detail/43573
  • 69. 69/129 2016 特別篇 3: MongoDB Ref: http://sql-vs-nosql.blogspot.tw/2013/11/indexes-comparison-mongodb-vs-mssqlserver.html
  • 70. 70/129 2016 特別篇 3: MongoDB Ref: http://learnmongodbthehardway.com/schema/chapter4/ B+Tree / Heap Table
  • 71. 71/129 2016 特別篇 3: MongoDB Ref: Indexing and Performance Tuning (2015-11-03).pdf (p39)
  • 72. 72/129 2016 特別篇 3: MongoDB Index ➀ ”統一命名為 _id” ➁ ”新增若未指定 _id” 值,會使用 ObjectId ➂ ObjectId 為 12-byte BSON 型態 ➊ 4-byte 為 UNIX 紀元時間 ➋ 3-byte 為機器識別碼 ➌ 2-byte 為 Process ID ➍ 3-byte 為隨機值 Ref: https://docs.mongodb.org/manual/reference/object-id/ “_id” : ObjectId(“563479cc8a8a4246bd27d784”) “_id” : ObjectId(“563479d48a8a4246bd27d785”) “_id” : ObjectId(“563479df8a8a4246bd27d786”) 循序式 UUID
  • 73. 73/129 2016 特別篇 3: MongoDB MMAPv1 儲存引擎 ➀ Memory-mapped files Ref: http://learnmongodbthehardway.com/schema/chapter3/
  • 74. 74/129 2016 特別篇 3: MongoDB MMAPv1 儲存引擎 ➀ Memory-mapped files ➁ Padding Ref: http://learnmongodbthehardway.com/schema/chapter3/
  • 75. 75/129 2016 特別篇 3: MongoDB MMAPv1 儲存引擎 ➀ Memory-mapped files ➁ Padding ➂ Fragmentation Ref: http://learnmongodbthehardway.com/schema/chapter3/
  • 76. 76/129 2016 特別篇 3: MongoDB MMAPv1 儲存引擎 ➀ Memory-mapped files ➁ Padding ➂ Fragmentation ➃ Collection-level locking (WiredTiger 為 Document-level) Ref: http://sql-vs-nosql.blogspot.tw/2013/11/indexes-comparison-mongodb-vs-mssqlserver.html
  • 77. 77/129 2016 特別篇 3: MongoDB MMAPv1 儲存引擎 ➀ Memory-mapped files ➁ Padding ➂ Fragmentation ➃ Collection-level locking (WiredTiger 為 Document-level) ➄ MongoDB 3.2 以前為預設引擎, 3.2 後換 WiredTiger Ref: https://docs.mongodb.org/manual/core/wiredtiger/
  • 78. 78/129 2016 特別篇 3: MongoDB MMAPv1 的 Fragmentation 問題 Ref: http://www.slideshare.net/mongodb/7-managing-a-maturing-mongo-db-ecosystem-charity-majors (p35) 左邊是大量 Fragmentation ; 右邊是修復 Fragmentation 後
  • 79. 79/129 2016 特別篇 3: MongoDB MMAPv1 的 Fragmentation 問題 動作:連續新增 5 個 Document Collection : {Document 1} {Document 2} {Document 3} {Document 4} {Document 5}
  • 80. 80/129 2016 特別篇 3: MongoDB MMAPv1 的 Fragmentation 問題 動作:更新 Document 3 情況一:新的 Document 3 大小 <= 原先大小 Collection : {Document 1} {Document 2} {Document 3} {Document 4} {Document 5} {Document 1} {Document 2} {Document 3‘} {Document 4} {Document 5}
  • 81. 81/129 2016 特別篇 3: MongoDB MMAPv1 的 Fragmentation 問題 動作:更新 Document 3 情況二:新的 Document 3 大小 > 原先大小 Collection : {Document 1} {Document 2} {Document 3} {Document 4} {Document 5} {Document 1} {Document 2} Free {Document 4} {Document 5} {Document 3‘}
  • 82. 82/129 2016 特別篇 3: MongoDB MMAPv1 的 Fragmentation 問題 動作:新增 Document 6 Collection : {Document 1} {Document 2} Free {Document 4} {Document 5} {Document 3‘}
  • 83. 83/129 2016 特別篇 3: MongoDB MMAPv1 的 Fragmentation 問題 動作:新增 Document 6 情況一: Document 6 大小 <= 原先 Document 3 (Free) 大小 Collection : {Document 1} {Document 2} {Document 6} {Document 4} {Document 5} {Document 3‘} {Document 1} {Document 2} Free {Document 4} {Document 5} {Document 3‘}
  • 84. 84/129 2016 特別篇 3: MongoDB MMAPv1 的 Fragmentation 問題 動作:新增 Document 6 情況二: Document 6 大小 > 原先 Document 3 (Free) 大小 Collection : {Document 1} {Document 2} Free {Document 4} {Document 5} {Document 3‘} {Document 6} {Document 1} {Document 2} Free {Document 4} {Document 5} {Document 3‘}
  • 85. 85/129 2016 特別篇 3: MongoDB 特色與改善 ➀ Sharding/Replica 較容易 ( 但 Sharding/Replica 只有 Primary 可寫 ) ➁ Dynamic schema ( 不是 Schemaless) ➂ 儲存引擎可抽換 ➊ MMAPv1 ➋ WiredTiger ➌ inMemory ➍ Devnull ➎ (RocksDB)
  • 86. 86/129 2016 特別篇 3: MongoDB 特色與改善 ➃ 寫入的 Locking level 改善 2.2 版前, Process-level lock ,一個 Mongod 實例一個鎖 2.8 版前, Database-level lock ,一個 DB 一個鎖 2.8 版之後, WiredTiger 提供 Document-level lock 3.0 版之後, MMAPv1 改為 Collection-level lock Ref: http://sql-vs-nosql.blogspot.tw/2013/11/indexes-comparison-mongodb-vs-mssqlserver.html
  • 87. 87/129 2016 特別篇 3: MongoDB 特色與改善 ➄ 支援 MapReduce 2.4 版前,使用 SpiderMonkey ,是 single threaded 2.4 版之後,改用 V8 engine ,改善問題 ➅ Single thread model ,大多時候只用到一顆 CPU (WiredTiger 已支援 Multiple CPUs)
  • 88. 2016 88/129 特別篇 4: RDMBS or NoSQL ? Q: 使用 RDBMS 還是 NoSQL ?
  • 89. 89/129 2016 特別篇 4: RDMBS or NoSQL ? Q: 使用 RDBMS 還是 NoSQL ? 是個偽命題,需視你的場景而定。
  • 90. 90/129 2016 特別篇 4: RDMBS or NoSQL ? 不過 RDBMS 及 NoSQL 的分界會愈來愈小。 過去的一些 RDBMS 已開始支援 NoSQL 特性, Microsoft SQL Server / Oracle / MySQL / PostgreSQL 都確定支援 JSON(B) 操作。 Percona / MariaDB 可抽換為 TokuDB 引擎, MariaDB 更可抽換為 Cassandra 引擎。 NoSQL 等也開始支援強一致性。
  • 91. 91/129 2016 特別篇 4: RDMBS or NoSQL ? 不過 RDBMS 及 NoSQL 的分界會愈來愈小。 過去的一些 RDBMS 已開始支援 NoSQL 特性, Microsoft SQL Server / Oracle / MySQL / PostgreSQL 都確定支援 JSON(B) 操作。 Percona / MariaDB 可抽換為 TokuDB 引擎, MariaDB 更可抽換為 Cassandra 引擎。 NoSQL 等也開始支援強一致性。 NewSQL
  • 92. 2016 92/129 特別篇 5: 黑暗執行緒案例 Q: 試著分析黑暗執行緒的文章。 【 GUID Primary Key 資料庫避雷守則】 Ref: http://blog.darkthread.net/post-2016-01-29-guid-as-pk-on-db.aspx
  • 93. 93/129 2016 特別篇 5: 黑暗執行緒案例 以架構設計而言,我更傾向讓應用伺服器決定 GUID / UUID 的值, 理由有幾個。 ➊ 未來若需要異質資料庫彼此交換資料, GUID / UUID 的衝突會 更小。例如若 SQL Server 要與 MySQL 交換, MySQL 沒有 NEWID / NEWSEQUENTIALID 函式,所以勢必要用另一種算法來計算 UUID , 而算法不同就可能破壞原本 GUID / UUID 不會重複的機率。 ➋ 資料庫在整體架構中,是最難以擴展的,所以我傾向讓資料庫做愈少 事情愈好。 GUID / UUID 是需要計算的,即使開銷很低,但若量大還是 很可觀,所以我還是會把計算的成本移至應用伺服器處理。
  • 94. 94/129 2016 特別篇 5: 黑暗執行緒案例 ➌ 應用伺服器脫離 SQL Server 後,就無法使用 NEWID 及 NEWSEQUENTIALID ,所以需要找 UUID 產生器。 UUID 產生器有 幾種版本, UUIDv1 是類循序性, UUIDv4 是亂序性,可以依業務 場景選擇所需。而且 UUIDv1 的類循序性不像 NEWSEQUENTIALID 這麼容易猜測。 ➍ 大規模架構中,全循序性 Insert 不一定是好事。想像一下,順序性 Insert 時,所有資料會集中在樹最右下角的 Leaf Page Insert ,當 Page 滿後,就必須 Page Split ,此時就一定有 Latch 。 Latch 會減 緩 Insert 的速度。再加上實際在硬碟寫入的 Block 也會變成是 Hotspot 。 所以有時候,適當非循序性所造成的 Fragmentation 有時反而會更快。 最後有可能會變成全順序性 Insert 不一定最快,全隨機性 Insert 也不 一定最好,反而中間找平衡才是最佳的。而這時把 UUID 的計算移到應 用伺服器,剛好可以滿足這點。
  • 96. 96/129 2016 特別篇 5: 黑暗執行緒案例 黑暗執行緒提供的表設計建議 4c.. cb.. ee.. 07.. 3b.. 4c.. 5b.. 9e.. cb.. ee.. Clustered Index ( 循序式 ) Nonclustered Index ( 亂序式 ) 3 6 7 1 2 3 4 5 6 7
  • 98. 98/129 2016 特別篇 5: 黑暗執行緒案例 假設已有五筆資料 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. 3 5 1 2 3 4 5 [SeqNo] [FlowId] ... 1 07.. ... 2 9e.. ... 3 3b.. ... 4 cb.. ... 5 5b.. ... 1 3 5 2 4 Nonclustered Index ( 亂序式 ) Clustered Index ( 循序式 )
  • 99. 99/129 2016 特別篇 5: 黑暗執行緒案例 尋找【 WHERE FlowId = “5b..” 】 IO 次數: 0 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. 3 5 1 2 3 4 5 [SeqNo] [FlowId] ... 1 07.. ... 2 9e.. ... 3 3b.. ... 4 cb.. ... 5 5b.. ... 1 3 5 2 4 Nonclustered Index ( 亂序式 ) Clustered Index ( 循序式 )
  • 100. 100/129 2016 特別篇 5: 黑暗執行緒案例 尋找【 WHERE FlowId = “5b..” 】 IO 次數: 1 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. 3 5 1 2 3 4 5 [SeqNo] [FlowId] ... 1 07.. ... 2 9e.. ... 3 3b.. ... 4 cb.. ... 5 5b.. ... 1 3 5 2 4 Nonclustered Index ( 亂序式 ) Clustered Index ( 循序式 )
  • 101. 101/129 2016 特別篇 5: 黑暗執行緒案例 尋找【 WHERE FlowId = “5b..” 】 IO 次數: 2 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. 3 5 1 2 3 4 5 [SeqNo] [FlowId] ... 1 07.. ... 2 9e.. ... 3 3b.. ... 4 cb.. ... 5 5b.. ... 1 3 5 2 4 Nonclustered Index ( 亂序式 ) Clustered Index ( 循序式 )
  • 102. 102/129 2016 特別篇 5: 黑暗執行緒案例 尋找【 WHERE FlowId = “5b..” 】 IO 次數: 3 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. 3 5 1 2 3 4 5 [SeqNo] [FlowId] ... 1 07.. ... 2 9e.. ... 3 3b.. ... 4 cb.. ... 5 5b.. ... 1 3 5 2 4 Nonclustered Index ( 亂序式 ) Clustered Index ( 循序式 )
  • 103. 103/129 2016 特別篇 5: 黑暗執行緒案例 尋找【 WHERE FlowId = “5b..” 】 IO 次數: 4 ( 完成 ) 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. 3 5 1 2 3 4 5 [SeqNo] [FlowId] ... 1 07.. ... 2 9e.. ... 3 3b.. ... 4 cb.. ... 5 5b.. ... 1 3 5 2 4 Nonclustered Index ( 亂序式 ) Clustered Index ( 循序式 )
  • 104. 104/129 2016 特別篇 5: 黑暗執行緒案例 新增【 SeqNo: 6, FlowID: 4c.. 】 IO 次數: 0 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. 3 5 1 2 3 4 5 [SeqNo] [FlowId] ... 1 07.. ... 2 9e.. ... 3 3b.. ... 4 cb.. ... 5 5b.. ... 6 4c.. ... 1 3 5 2 4 Nonclustered Index ( 亂序式 ) Clustered Index ( 循序式 )
  • 105. 105/129 2016 特別篇 5: 黑暗執行緒案例 新增【 SeqNo: 6, FlowID: 4c.. 】 IO 次數: 1 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. 3 5 1 2 3 4 5 [SeqNo] [FlowId] ... 1 07.. ... 2 9e.. ... 3 3b.. ... 4 cb.. ... 5 5b.. ... 6 4c.. ... 1 3 5 2 4 Nonclustered Index ( 亂序式 ) Clustered Index ( 循序式 )
  • 106. 106/129 2016 特別篇 5: 黑暗執行緒案例 新增【 SeqNo: 6, FlowID: 4c.. 】 IO 次數: 2 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. 3 5 1 2 3 4 5 [SeqNo] [FlowId] ... 1 07.. ... 2 9e.. ... 3 3b.. ... 4 cb.. ... 5 5b.. ... 6 4c.. ... 1 3 5 2 4 Nonclustered Index ( 亂序式 ) Clustered Index ( 循序式 )
  • 107. 107/129 2016 特別篇 5: 黑暗執行緒案例 新增【 SeqNo: 6, FlowID: 4c.. 】 IO 次數: 3+3 Page Split 次數: 1 3 5 1 2 3 4 5 [SeqNo] [FlowId] ... 1 07.. ... 2 9e.. ... 3 3b.. ... 4 cb.. ... 5 5b.. ... 6 4c.. ... Nonclustered Index ( 亂序式 ) Clustered Index ( 循序式 ) 07.. 3b.. 4c.. 5b.. 1 3 6 5 42 3b.. 5b.. cb.. 9e.. cb..
  • 108. 108/129 2016 特別篇 5: 黑暗執行緒案例 新增【 SeqNo: 6, FlowID: 4c.. 】 IO 次數: 3+3+1 Page Split 次數: 1 3 5 1 2 3 4 5 [SeqNo] [FlowId] ... 1 07.. ... 2 9e.. ... 3 3b.. ... 4 cb.. ... 5 5b.. ... 6 4c.. ... Nonclustered Index ( 亂序式 ) Clustered Index ( 循序式 ) 07.. 3b.. 4c.. 5b.. 1 3 6 5 42 3b.. 5b.. cb.. 9e.. cb..
  • 109. 109/129 2016 特別篇 5: 黑暗執行緒案例 新增【 SeqNo: 6, FlowID: 4c.. 】 IO 次數: 3+3+2 Page Split 次數: 1 3 5 1 2 3 4 5 [SeqNo] [FlowId] ... 1 07.. ... 2 9e.. ... 3 3b.. ... 4 cb.. ... 5 5b.. ... 6 4c.. ... Nonclustered Index ( 亂序式 ) Clustered Index ( 循序式 ) 07.. 3b.. 4c.. 5b.. 1 3 6 5 42 3b.. 5b.. cb.. 9e.. cb..
  • 110. 110/129 2016 特別篇 5: 黑暗執行緒案例 新增【 SeqNo: 6, FlowID: 4c.. 】 IO 次數: 3+3+3 Page Split 次數: 1 3 5 1 2 3 4 5 6 [SeqNo] [FlowId] ... 1 07.. ... 2 9e.. ... 3 3b.. ... 4 cb.. ... 5 5b.. ... 6 4c.. ... Nonclustered Index ( 亂序式 ) Clustered Index ( 循序式 ) 07.. 3b.. 4c.. 5b.. 1 3 6 5 42 3b.. 5b.. cb.. 9e.. cb..
  • 111. 111/129 2016 特別篇 5: 黑暗執行緒案例 新增【 SeqNo: 6, FlowID: 4c.. 】 IO 次數: 3+3+4=10 ( 完成 ) Page Split 次數: 1 07.. 3b.. 4c.. 5b.. 3 6 1 2 3 4 5 6 [SeqNo] [FlowId] ... 1 07.. ... 2 9e.. ... 3 3b.. ... 4 cb.. ... 5 5b.. ... 6 4c.. ... 1 3 6 5 42 Nonclustered Index ( 亂序式 ) Clustered Index ( 循序式 ) 3b.. 5b.. cb.. 9e.. cb..
  • 112. 112/129 2016 特別篇 5: 黑暗執行緒案例 如果用一般亂序式 UUID [FlowId] ... ... 07.. ... ... 9e.. ... ... 3b.. ... ... cb.. ... ... 5b.. ... ... 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. Clustered Index ( 亂序式 )
  • 113. 113/129 2016 特別篇 5: 黑暗執行緒案例 尋找【 WHERE FlowId = “5b..” 】 IO 次數: 0 [FlowId] ... ... 07.. ... ... 9e.. ... ... 3b.. ... ... cb.. ... ... 5b.. ... ... 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. Clustered Index ( 亂序式 )
  • 114. 114/129 2016 特別篇 5: 黑暗執行緒案例 尋找【 WHERE FlowId = “5b..” 】 IO 次數: 1 [FlowId] ... ... 07.. ... ... 9e.. ... ... 3b.. ... ... cb.. ... ... 5b.. ... ... 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. Clustered Index ( 亂序式 )
  • 115. 115/129 2016 特別篇 5: 黑暗執行緒案例 尋找【 WHERE FlowId = “5b..” 】 IO 次數: 2 ( 完成 ) [FlowId] ... ... 07.. ... ... 9e.. ... ... 3b.. ... ... cb.. ... ... 5b.. ... ... 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. Clustered Index ( 亂序式 )
  • 116. 116/129 2016 特別篇 5: 黑暗執行緒案例 新增【 FlowID: 4c.. 】 IO 次數: 0 [FlowId] ... ... 07.. ... ... 9e.. ... ... 3b.. ... ... cb.. ... ... 5b.. ... ... 4c.. ... ... 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. Clustered Index ( 亂序式 )
  • 117. 117/129 2016 特別篇 5: 黑暗執行緒案例 新增【 FlowID: 4c.. 】 IO 次數: 1 [FlowId] ... ... 07.. ... ... 9e.. ... ... 3b.. ... ... cb.. ... ... 5b.. ... ... 4c.. ... ... 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. Clustered Index ( 亂序式 )
  • 118. 118/129 2016 特別篇 5: 黑暗執行緒案例 新增【 FlowID: 4c.. 】 IO 次數: 2 [FlowId] ... ... 07.. ... ... 9e.. ... ... 3b.. ... ... cb.. ... ... 5b.. ... ... 4c.. ... ... 5b.. cb.. 07.. 3b.. 5b.. 9e.. cb.. Clustered Index ( 亂序式 )
  • 119. 119/129 2016 特別篇 5: 黑暗執行緒案例 新增【 FlowID: 4c.. 】 IO 次數: 3+3 ( 完成 ) Page Split 次數: 1 [FlowId] ... ... 07.. ... ... 9e.. ... ... 3b.. ... ... cb.. ... ... 5b.. ... ... 4c.. ... ... 3b.. 5b.. cb.. 07.. 3b.. 4c.. 5b.. Clustered Index ( 亂序式 ) 9e.. cb..
  • 120. 120/129 2016 特別篇 5: 黑暗執行緒案例 如果用一般循序式 UUID [FlowId] ... ... 1 ... ... 2 ... ... 3 ... ... 4 ... ... 5 ... ... 3 5 1 2 3 4 5 Clustered Index ( 循序式 )
  • 121. 121/129 2016 特別篇 5: 黑暗執行緒案例 尋找【 WHERE FlowId = 5 】 IO 次數: 0 [FlowId] ... ... 1 ... ... 2 ... ... 3 ... ... 4 ... ... 5 ... ... 3 5 1 2 3 4 5 Clustered Index ( 循序式 )
  • 122. 122/129 2016 特別篇 5: 黑暗執行緒案例 尋找【 WHERE FlowId = 5 】 IO 次數: 1 [FlowId] ... ... 1 ... ... 2 ... ... 3 ... ... 4 ... ... 5 ... ... 3 5 1 2 3 4 5 Clustered Index ( 循序式 )
  • 123. 123/129 2016 特別篇 5: 黑暗執行緒案例 尋找【 WHERE FlowId = 5 】 IO 次數: 2 ( 完成 ) [FlowId] ... ... 1 ... ... 2 ... ... 3 ... ... 4 ... ... 5 ... ... 3 5 1 2 3 4 5 Clustered Index ( 循序式 )
  • 124. 124/129 2016 特別篇 5: 黑暗執行緒案例 新增【 FlowID: 6 】 IO 次數: 0 [FlowId] ... ... 1 ... ... 2 ... ... 3 ... ... 4 ... ... 5 ... ... 6 ... ... 3 5 1 2 3 4 5 Clustered Index ( 循序式 )
  • 125. 125/129 2016 特別篇 5: 黑暗執行緒案例 新增【 FlowID: 6 】 IO 次數: 1 [FlowId] ... ... 1 ... ... 2 ... ... 3 ... ... 4 ... ... 5 ... ... 6 ... ... 3 5 1 2 3 4 5 Clustered Index ( 循序式 )
  • 126. 126/129 2016 特別篇 5: 黑暗執行緒案例 新增【 FlowID: 6 】 IO 次數: 2 [FlowId] ... ... 1 ... ... 2 ... ... 3 ... ... 4 ... ... 5 ... ... 6 ... ... 3 5 1 2 3 4 5 Clustered Index ( 循序式 )
  • 127. 127/129 2016 特別篇 5: 黑暗執行緒案例 新增【 FlowID: 6 】 IO 次數: 3+1 ( 完成 ) [FlowId] ... ... 1 ... ... 2 ... ... 3 ... ... 4 ... ... 5 ... ... 6 ... ... 3 6 1 2 3 4 5 6 Clustered Index ( 循序式 )
  • 128. 128/129 2016 特別篇 5: 黑暗執行緒案例 小結:本場景為例 黑暗執行緒 亂序式 UUID 循序式 UUID Point-of-query IO 4 2 2 Insert IO 10 6 4 Insert (Page Split) 1 1 0 Space size ++ + + Latch(%) ++ + +
  • 129. 129/129 2016 特別篇 6: MultiColumn B-Tree Index [Col#1] [Col#2] 1 A 3 B 3 C 4 D 3 C CREATE INDEX ON table (Col#1, Col#2); 1 A 3 B 3 C 4 D