MySQL 聚簇索引 和覆蓋索引

一.聚簇索引
1.聚簇索引並非一種單獨因此,而是一種數據儲存方式。
InnoDB 的聚簇索引實際上在同一結構中保存了B-Tree 索引和數據行。mysql

2.當表有聚簇索引時,它的數據行實際上存放在索引的葉子頁中。「聚簇」表示數據行和相鄰的鍵值緊湊的儲存在一塊兒。sql

3.對應InnoDB 來講若是表沒有定義主鍵,會選擇一個惟一的非空索引代替。若是沒有這樣的索引InnoDB 會隱式定義一個主鍵來做爲聚簇索引。InnoDB 只彙集在同一頁面中的記錄。緩存

4.聚簇索引的優點:性能

(1)能夠把相關數據保存在一塊兒。
(2)數據訪問更快。數據和索引保存在同一個 B-Tree 。
(3)使用覆蓋索引掃描的查詢能夠直接使用頁節點的主鍵值

5.聚簇索引的缺點:操作系統

(1)聚簇索引最大的提升了I/O密集型應用的性能,但若是數據所有都放到內存中,則數據的順序就沒有那麼重要了,聚簇索引也就沒什麼優點了。

(2)插入速度嚴重依賴插入順序。按照主鍵插入的方式是InnoDB 速度最快的方式,但若是不是按照主鍵順序加載數據,那麼在加載後最好使用OPTIMIZE TABLE 命令從新組織一2下表
(3)更新聚簇索引列的代價很高。由於會強制InnoDB 將每一個被更新的行移動到新的位置code

6.二級索引索引

主鍵索引的葉子節點存的是整行數據,在InnoDB 裏,主鍵索引也被稱爲聚簇索引

非主鍵索引的葉子節點內容是主鍵的值。在InnoDB 裏。非主鍵索引也被稱爲二級索引。
如:select* from order where user_id=3; user_id是普通索引。則會先搜索user_id 的索引樹,獲得id=5,再到id 索引樹搜索一次,這個過程就是 「回表」。
也就是說非主鍵索引須要查詢2次內存

二.覆蓋索引
1.mysql 可使用索引直接來獲取列的數據,這樣就能夠再也不須要讀取數據行。
若是索引的葉子節點中已經包含要查詢的數據,那麼還有什麼必要再回表查詢呢?若是一個索引包含(覆蓋)全部要查詢的字段的值,那麼就稱爲「覆蓋索引」select

2.覆蓋索引能夠提升查詢的性能,不須要會表,好處是:搜索

(1)索引條目一般小於數據行,若是隻需讀取索引,那麼mysql 就會減小訪問量
(2)索引是按照列值順序存儲的,索引I/O 密集型的範圍查詢會比隨機從磁盤讀取每一行數據的I/O 要少得多
(3)一些存儲引擎如MyISAM 在內存只緩存索引,數據則依賴操做系統來緩存,所以要訪問數據須要一次系統調用,這可能致使嚴重的性能問題,尤爲是那些系統調用佔了數據訪問中最大開銷的場景
(4)InnoDB 的聚簇索引,覆蓋索引對InnoDB 表的特別有用。InnoDB 的二級索引在葉子節點保存了行的主鍵值,因此若是二級主鍵可以覆蓋查詢,則能夠避免對主鍵索引的二次查詢。

3
select id from order where user_id between 1 and 3
這時候只須要查ID 的值,而ID 已經在user_id 索引樹上,所以能夠直接提供查詢結果,不須要回表。

select * from order where user_id between 1 and 3
一旦用了select *,就會有其餘列須要讀取,這時在讀完index之後還須要去讀data纔會返回結果。

這兩種處理方式性能差別很是大,特別是返回行數比較多,而且讀數據須要 I/O 的時候,可能會有幾十上百倍的差別。所以建議根據須要用select *


ps:文章參考《高性能mysql》一書

相關文章
相關標籤/搜索