MySQL 深入分析MySQL索引機制的實現

2021-09-25 18:32:46 字數 2890 閱讀 1377

資料庫是乙個只要從事後端開發,就永遠離不開的技術,大部分企業選擇的資料庫都是mysql,所以需要我們對mysql有著足夠的了解。

而mysql索引,我們都知道提高效能要加索引,也知道索引的結構是b-tree,也都可以說出幾條加索引的原則,但再深入一點,往往就會詞窮,這可能就是知其然而不知其所以然的結果了。這會讓我們在實際的開發中,涉及到究竟要給哪個欄位加索引,就「拄杖落手心茫然」了。

於是我就問了自己這樣幾個問題,索引究竟是什麼呢?索引是存在**的呢?mysql是怎樣通過索引,就優化了效能呢?

本文的研究物件是innodb儲存引擎,其他儲存引擎並沒有涉及。

首先想要了解索引究竟存在**,如何發揮作用,就不能只研究索引,要結合整個資料庫的儲存結構,執行流程,來分析索引是如何優化查詢過程的。

【一】mysql的邏輯儲存結構

關於乙個頁的具體組成,可以從下圖中有乙個更直觀的認識:

各個資料頁之間通過雙向鍊錶連線,每個頁內各條行記錄用單鏈表連線。

如果沒有任何索引優化,在查詢資料時只能先遍歷雙向鍊錶找到對應的頁,加了索引,就可以通過索引的b+樹結構定位對應的頁。

【二】實驗mysql的資料儲存

為了有更清晰的認識,我們在資料庫中做乙個實驗,

在資料庫建立member表,結構如下

drop table if exists `member`;

create table `member` (

`id` int(10) not null auto_increment,

`name` varchar(255) default null,

`***` 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中資料的儲存方式,在這種儲存結構中,同時儲存了索引和資料行。

簡要聚集索引特點:

按照主鍵構建b+樹

葉子節點就是資料頁(存了該行記錄的所有資料)

一張表只能有乙個聚集索引

【四】索引的使用

【五】幾種型別索引的常用操作:

參考:《mysql技術內幕-innodb儲存引擎》

《高效能mysql》

深入分析Mysql中limit的用法

mysql中limit的用法 在我們使用查詢語句的時候,經常要返回前幾條或者中間某幾行資料,這個時候怎麼辦呢?不用擔心,mysql已經為我們提供了這樣乙個功能。select from table limit offset rows rows offset offsetlimit 子句可以被用於強制 ...

MySQL 資料庫事務深入分析

推薦閱讀 吊打面試官!mysql靈魂100問,你能答出多少?只有innodb引擎支援事務,下邊的內容均以innodb引擎為預設條件 乙個事務讀取了另乙個事務未提交的資料 乙個事務對同一資料的讀取結果前後不一致。兩次讀取中間被其他事務修改了 幻讀是指事務讀取某個範圍的資料時,因為其他事務的操作導致前後...

基於Mysql儲存引擎的深入分析

mysql有很多種儲存引擎,針對不同的應用,可以為每張表選擇合適的儲存引擎,這樣有助於提公升mysql效能。建立新聞表news 複製 如下 create table sandbox news id int not null auto increment name varchar 45 null co...