mysql為什麼加索引就能快

2021-09-19 11:13:01 字數 1651 閱讀 7438

平時我們要優化 mysql 查詢效率的時候,最常見的就是給表加上合適的索引了,那今天就來聊聊為什麼加了索引就快了呢。

很多人會說索引就相當於一本書的目錄,通過目錄來找書中的某一頁,確實是很快的,如果沒有目錄,就需要一頁一頁的去翻書了,大大降低了效率。這個比喻其實還挺恰當的,也是乙個很經典的索引比喻了。

在 innodb 中,每個索引其實都是一顆 b+ 樹,主鍵索引稱作聚簇索引,其他非主鍵索引稱作二級索引,每個表中每一行的記錄值都完整的儲存在主鍵索引的葉子節點上,二級索引的葉子節點儲存的是主鍵的值

mysql 索引其實就是一顆 b+ 樹。

也就是說每個表至少都有乙個主鍵索引,而且表中所有的資料行都是存放在主鍵索引這個 b+ 樹的葉子節點上的。如果你給表的其他欄位加了索引的話,這個索引就是二級索引了,二級索引也是 b+ 樹。

二級索引和主鍵索引的不同之處在於其葉子節點上儲存的值不一樣,表中所有欄位的值都被完整的儲存在主鍵索引的葉子節點上,但是二級索引的葉子節點只儲存對應主鍵的值。

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

mysql> create table t(

id int primary key, 

k int not null, 

m int(11),

index (k)) engine=innodb;

然後再給表中插入幾條資料,用r1、r2、r3、r4、r5表示,插入的具體資料如下:r1~r5 的 (id,k,m) 值分別為 (100,1,1000)、(200,2,2000)、(300,3,3000)、(500,5,5000)、(600,6,6000)。

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

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

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

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

select * from t where m > 1000 and m
再來看另一條 sql 語句,這個語句可以使用索引 k,所以該查詢會先到二級索引 k 這個 b+ 樹上,快速找到滿足要求的葉子節點,而這裡的葉子節點上只儲存了主鍵的值,所以還需要通過獲得的主鍵 id 值再回到主鍵索引上查出所有欄位的值,這個過程稱作回表

select * from t where k > 3 and k < 6;
這就是為什麼加了索引後,mysql 查詢會變快的原因了,其實剛提到的這個回表過程還可以再優化的,就是利用覆蓋索引,後面的文章我們再詳細說。

Redis為什麼會比MySQL快?

1.redis是基於記憶體儲存的,mysql是基於磁碟儲存的 2.redis儲存的是k v格式的資料。時間複雜度是o 1 常數階,而mysql引擎的底層實現是b tree,時間複雜度是o logn 對數階。redis會比mysql快一點點。3.mysql資料儲存是儲存在表中,查詢資料時要先對錶進行全...

redis 為什麼比mysql快

redis是基於記憶體儲存的,mysql是基於磁碟儲存的 redis儲存的是k v格式的資料。時間複雜度是o 1 常數階,而mysql引擎的底層實現是b tree,時間複雜度是o logn 對數階。redis會比mysql快一點點。mysql資料儲存是儲存在表中,查詢資料時要先對錶進行全域性掃瞄或者...

Redis為什麼會比MySQL快?

1.redis是基於記憶體儲存的,mysql是基於磁碟儲存的 2.redis儲存的是k v格式的資料。時間複雜度是o 1 常數階,而mysql引擎的底層實現是b tree,時間複雜度是o logn 對數階。redis會比mysql快一點點。3.mysql資料儲存是儲存在表中,查詢資料時要先對錶進行全...