mysql爲何加索引就能快

平時咱們要優化 mysql 查詢效率的時候,最多見的就是給表加上合適的索引了,那今天就來聊聊爲何加了索引就快了呢。mysql

不少人會說索引就至關於一本書的目錄,經過目錄來找書中的某一頁,確實是很快的,若是沒有目錄,就須要一頁一頁的去翻書了,大大下降了效率。這個比喻其實還挺恰當的,也是一個很經典的索引比喻了。sql

在 InnoDB 中,每一個索引其實都是一顆 B+ 樹,主鍵索引稱做聚簇索引,其餘非主鍵索引稱做二級索引,每一個表中每一行的記錄值都完整的保存在主鍵索引的葉子節點上,二級索引的葉子節點保存的是主鍵的值。post

mysql 索引其實就是一顆 B+ 樹。 juejin.im/post/5c8dce…優化

也就是說每一個表至少都有一個主鍵索引,並且表中全部的數據行都是存放在主鍵索引這個 B+ 樹的葉子節點上的。若是你給表的其餘字段加了索引的話,這個索引就是二級索引了,二級索引也是 B+ 樹。cdn

二級索引和主鍵索引的不一樣之處在於其葉子節點上保存的值不同,表中全部字段的值都被完整的保存在主鍵索引的葉子節點上,可是二級索引的葉子節點只保存對應主鍵的值。blog

咱們舉一個具體的例子來還原下這個問題。首先提供一個表,表中有三個字段 (id,k,m),分別給主鍵 id 和字段 k 創建主鍵索引和二級索引。索引

mysql> create table t( id int primary key, k int not null, m int(11), index (k)) engine=InnoDB;圖片

而後再給表中插入幾條數據,用R一、R二、R三、R四、R5表示,插入的具體數據以下:R1~R5 的 (id,k,m) 值分別爲 (100,1,1000)、(200,2,2000)、(300,3,3000)、(500,5,5000)、(600,6,6000)。get

剛剛有說過,主鍵索引葉子節點上保存完整的整行記錄值,二級索引葉子節點保存主鍵的值,因此上面這個表 t 的數據在 mysql 底層的存儲就以下示意圖。it

表 t 一共有 3 個字段,字段 m 上沒有索引,也就是說表 t 上有兩個索引,因此對應有 2 個 B+ 樹,一個表上有多少個索引,其實就會有多少個 B+ 樹。

接下來再來看下有索引和沒有索引的查詢區別。

好比下面這條 sql 語句,顯然沒有可用的索引,因此只能走全表掃描了,即把主鍵索引上的葉子節點從頭至尾都掃描一遍,而後每掃描到一行把字段 m 的值拿出來再比對一下,篩選出知足條件的記錄,這個查詢是很是低效的。

select * from t where m > 1000 and m < 3000;

再來看另外一條 sql 語句,這個語句可使用索引 k,因此該查詢會先到二級索引 k 這個 B+ 樹上,快速找到知足要求的葉子節點,而這裏的葉子節點上只保存了主鍵的值,因此還須要經過得到的主鍵 ID 值再回到主鍵索引上查出全部字段的值,這個過程稱做回表

select * from t where k > 3 and k < 6;

這就是爲何加了索引後,mysql 查詢會變快的緣由了,其實剛提到的這個回表過程還能夠再優化的,就是利用覆蓋索引,後面的文章咱們再詳細說。

有問題歡迎留言交流,原創不易,若是文章對你有幫助,但願能給文章點個贊,感謝支持,另外文中圖片來源於極客時間專欄。

相關文章
相關標籤/搜索