主鍵索引 (聚集索引) 和普通索引 (輔助索引) 的區別

carlclone發表於2019-04-06
  • 什麼是聚集索引?

    首先innodb引擎預設在主鍵上建立聚集索引 , 通常說的主鍵索引就是聚集索引 , 聚集索引會儲存行上的所有資料, 因此不需要額外的IO

  • 什麼是輔助索引?

    輔助索引(Secondary Index) , 葉子節點只儲存了行的鍵值和指向對應行的"書籤" , 一般指向的是聚集索引 , 此外innodb實現了覆蓋索引(Covering index) , 即葉子節點除了儲存該行的鍵值還儲存了對應索引列的值 , 如果不需要額外資料的話則不需要另外對聚集索引中的資料進行IO

    注: SQL Server的主鍵索引和普通索引的區別僅僅是唯一非空,而mysql innodb下不是, 另外嚴格來說主鍵是約束

  • 為什麼性別列和其他低選擇性的列不適合加索引?

    因為你訪問索引需要付出額外的IO開銷,你從索引中拿到的只是地址,要想真正訪問到資料還是要對錶進行一次IO。假如你要從表的100萬行資料中取幾個資料,那麼利用索引迅速定位,訪問索引的這IO開銷就非常值了。但如果你是從100萬行資料中取50萬行資料,就比如性別欄位,那你相對需要訪問50萬次索引,再訪問50萬次表,加起來的開銷並不會比直接對錶進行一次完整掃描小。

    當然凡事不是絕對,如果把性別欄位設為表的聚集索引,那麼就肯定能加快大約一半該欄位的查詢速度了。聚集索引指的是表本身中資料按哪個欄位的值來進行排序。因此,聚集索引只能有一個,而且使用聚集索引不會付出額外IO開銷。當然你得能捨得把聚集索引這麼寶貴資源用到性別欄位上。從性別欄位不適合建索引說起

  • 優化器為什麼會選擇覆蓋索引用於count() 等統計問題?

    因為覆蓋索引遠小於聚集索引 , 可以減少磁碟IO操作

理解不一定正確,只作為記錄,各位多多指教

參考

MySQL技術內幕:innodb儲存引擎-第五章

高效能MySQL第三版 3.3剖析mysql查詢 第6章 查詢效能的優化

相關文章