mysql 回滚段_史上最牛分析MySQL索引机制的实现!不接受反驳
數據庫是一個只要從事后端開發,就永遠離不開的技術,大部分企業選擇的數據庫都是MySQL,所以需要我們對MySQL有著足夠的了解。
而MySQL索引,我們都知道提高性能要加索引,也知道索引的結構是B-Tree,也都可以說出幾條加索引的原則,但再深入一點,往往就會詞窮,這可能就是知其然而不知其所以然的結果了。這會讓我們在實際的開發中,涉及到究竟要給哪個字段加索引,就“拄杖落手心茫然”了。
于是我就問了自己這樣幾個問題,索引究竟是什么呢?索引是存在哪里的呢?MySQL是怎樣通過索引,就優化了性能呢?
本文的研究對象是InnoDB存儲引擎,其他存儲引擎并沒有涉及。
首先想要了解索引究竟存在哪里,如何發揮作用,就不能只研究索引,要結合整個數據庫的存儲結構,運行流程,來分析索引是如何優化查詢過程的。
【一】MySQL的邏輯存儲結構
- 表空間(tablespace):可以默認為存儲引擎邏輯結構的最高層,存放所有的數據。
- 段(segment):包括數據段、索引段、回滾段,對于段的管理,由存儲引擎自身完成。
- 區(extent):1MB,一個區64個頁,InnoDB一次從磁盤申請4~5個區,一個區中有連續的64個頁。
- 頁(page)/塊(block):每個頁固定大小16KB。
- 行(row):有Compact和Redundant兩種行存儲格式。
關于一個頁的具體組成,可以從下圖中有一個更直觀的認識:
各個數據頁之間通過雙向鏈表連接,每個頁內各條行記錄用單鏈表連接。
如果沒有任何索引優化,在查詢數據時只能先遍歷雙向鏈表找到對應的頁,加了索引,就可以通過索引的B+樹結構定位對應的頁。
【二】實驗MySQL的數據存儲
為了有更清晰的認識,我們在數據庫中做一個實驗,
在數據庫創建member表,結構如下
DROP TABLE IF EXISTS `member`;CREATE TABLE `member` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `sex` smallint(2) DEFAULT NULL, `desc` text, PRIMARY KEY (`id`), UNIQUE KEY(`id`,`NAME`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;創建表后,member.ibd大小是112KB,可見有7個頁,然后用《MySQL技術內幕-InnoDB存儲引擎》中提到的python小工具,查看表空間中各個頁的信息,其中有offset為3和4的兩個數據頁,此時還沒有索引節點。
中間出現的小插曲,導入下面的數據,發現頁信息是這樣的,:
INSERT INTO `member` SELECT '1', '李白', '1', REPEAT('且放白鹿青崖間',500);INSERT INTO `member` SELECT '2', '蘇軾', '1', REPEAT('暮云收盡溢清寒',500);INSERT INTO `member` SELECT '3', '白居易', '1',REPEAT('我寄人間雪滿頭',500);INSERT INTO `member` SELECT '4', '姜夔', '1',REPEAT('淮南皓月冷千山',500);出現這種情況是因為,當行記錄的長度超過行記錄最大長度時,變長列(variable-length column)會選擇外部溢出頁(overflow page,一般是Uncompressed BLOB Page)進行存儲,于是調整desc列的長度:
INSERT INTO `member` SELECT '1', '李白', '1', REPEAT('且放白鹿青崖間',300);INSERT INTO `member` SELECT '2', '蘇軾', '1', REPEAT('暮云收盡溢清寒',300);INSERT INTO `member` SELECT '3', '白居易', '1',REPEAT('我寄人間雪滿頭'300);INSERT INTO `member` SELECT '4', '姜夔', '1',REPEAT('淮南皓月冷千山',300);我們知道,InnoDB中,表是根據主鍵順序存儲的(索引組織表),
上圖是page offset為3的數據構成,藍框的部分是File Header和Page Header,紅框的部分是Infimum Records,后面是Supremum Records。
通過Infimum Records可以找到主鍵為1的鍵值,就是綠框的部分,后面的值00 00 00 05就是數據頁頁號,再后面分別是主鍵為2和4對應的Pointer。
【三】聚集索引
InnoDB存儲引擎中,表是索引組織表,所以準確來講,聚集索引不是一種索引類型,而是一種InnoDB中數據的存儲方式,在這種存儲結構中,同時保存了索引和數據行。
簡要聚集索引特點:
【四】索引的使用
- 不同應用中有區別:
- 聯合索引
- 覆蓋索引
- 一些老生常談的索引使用建議,在日常使用時,要知其然并知其所以然,才能將索引用好
【五】幾種類型索引的常用操作:
- 普通索引
- 唯一索引:唯一索引與普通索引的不同點在于,普通索引列允許重復值,唯一索引列值必須唯一,但允許NULL值。
- 主鍵索引:是特殊的唯一索引,不允許NULL值,一個表中只有一個。
- 組合索引
總結
以上是生活随笔為你收集整理的mysql 回滚段_史上最牛分析MySQL索引机制的实现!不接受反驳的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: filter函数的用法_这几个超牛函数,
- 下一篇: python从mysql导出大量数据_p