在查詢當中,如果是通過主鍵來查詢資料,即使用explain分析sql的key顯示primary時,查詢效率是最高的,因為葉子節點存放的就是資料記錄本身,所有可以直接返回,而不需要像非聚簇索引一樣需要通過額外的隨機磁碟訪問獲取資料記錄。
其次是對於order by排序操作,如果order by的列是主鍵,則由於主鍵索引對應的b+樹本身是有序的, 故儲存引擎返回的資料就是已經根據主鍵有序的,不需要在mysql伺服器層再進行排序,提高了效能,如果通過explain分析sql時,extra顯示using filesort,則說明需要在mysql伺服器層進行排序,這種情況一般需要想辦法優化。
對於基於主鍵的範圍查詢,由於聚簇索引的葉子節點已經根據主鍵的順序,使用雙向鍊錶進行了相連,故可以快速找到某一範圍的資料記錄。
輔助索引
輔助索引也稱為二級索引,是一種非聚簇索引,一般是為了提高某些查詢的效率而設計的,即使用該索引列查詢時,通過輔助索引來避免全表掃瞄。由於輔助索引不是聚簇索引,索引每個表可以存在多個輔助索引,結構如下:
輔助索引的非葉子節存放索引列的關鍵字,葉子節點存放指向聚簇索引(或者說是主鍵索引)的主鍵的指標。即通過輔助索引定位到需要的資料後,如果不能通過索引覆蓋所需列,即通過該輔助索引列來獲取該次查詢所需的所有資料列,則需要通過該指向聚簇索引的主鍵的指標定位到在聚簇索引中的主鍵,然後再通過該主鍵值在聚簇索引中找到對應的葉子頁,從而獲取到對應的資料記錄,所以整個過程涉及到先在輔助索引中查詢,再在聚簇索引(即主鍵索引)中查詢(回表查詢)兩個過程。
舉個例子:
輔助索引對應的b+樹的高度為3,則需要3次磁碟io來定位到葉子節點,其中葉子節點包含指向聚簇索引的某個主鍵值的指標;
然後通過葉子節點的指向聚簇索引的主鍵值的指標,在聚簇索引中根據該主鍵值找到對應的資料記錄,即如果聚簇索引對應的b+樹高度也是3,則也需要3次磁碟io來定位到聚簇索引的葉子頁,從而在該葉子頁中獲取實際的資料記錄
以上過程總共需要進行6次磁碟io。故如果需要回表查詢的資料行較多,則所需的磁碟io將會成倍增加,查詢效能會下降。所以需要在過濾程度高,即重複資料少的列來建立輔助索引。
cardinality:索引列的資料重複度
由以上分析可知,通過輔助索引進行查詢時,如果需要回表查詢並且查詢的資料行較多時,需要大量的磁碟io來獲取資料,故這種索引不但沒有提供查詢效能,反而會降低查詢效能。所以輔助索引所選擇的列需要是重複讀低的列,即一般查詢後只需要返回一兩行資料。如果該列存在太多的重複值,則需要考慮放棄在該列建立輔助索引。
具體可以通過show index的cardinality的值來判斷,cardinality表示索引列的唯一值的估計數量,如果跟資料行的數量接近,則說明該列存在的重複值少,列的過濾性較好;如果相差太大,即cardinality / 資料行總數,的值太小,如性別列只包含「男」,「女」兩個值,則說明該列存在大量重複值,需要考慮是否刪除該索引。
覆蓋索引
由於回表查詢開銷較大,故為了減少回表查詢的次數,可以在輔助索引中增加查詢所需要的所有列,如使用聯合索引,這樣可以從輔助索引中獲取查詢所需的所有資料,不需要回表查詢完整的資料行,從而提高效能,這種機制稱為覆蓋索引。
當使用explain分析查詢sql時,如果extra顯示 using index 則說明使用了覆蓋索引返回資料,該查詢效能較高。
由於索引的存在會增加更新資料的開銷,即更新資料時,如增加和刪除資料行,需要通過更新對應的輔助索引,故在具體設計時,需要在兩者之間取個折中。
聯合索引與最左前戳匹配
聯合索引是使用多個列作為索引,如(a,b,c),表示使用a,b,c三個列來作為索引,由b+樹的特徵可知,索引都是需要符合最左前戳匹配的,故其實相當於建立a,(a,b),(a,b,c)三個索引。
所以在設計聯合索引時,除了需要考慮是否可以優化為覆蓋索引外,還需要考慮多個列的順序,一般的經驗是:查詢頻率最高,過濾性最好(重複值較少)的列在前,即左邊。
除此之外,可以考慮通過聯合索引來減少mysql服務端層的排序,如使用者訂單表包含聯合索引(user_id, buy_date),主鍵索引為user_id,如果只是普通的查詢某個使用者的訂單,則innodb會使用user_id主鍵索引,但是當需要基於購買日期buy_date來排序並取出該使用者最近3天的購買記錄時,則主鍵索引和聯合索引(user_id, buy_date)都可以使用,innodb會選擇使用聯合索引,因為在該聯合索引中buy_date已經有序了,故不需要再在mysql伺服器層進行一次排序,從而提高了效能。
InnoDB儲存引擎(四)索引
在本篇部落格中,我將介紹資料索引的原理 實現。innodb支援三種索引 聚集索引特點 聚集索引優點 非聚集索引特點 該值表示某個表的字段是否具有高選擇性,用來看是否應該建立索引。比如性別這種,是低選擇性的,取值範圍只有2個,而記錄有成千上萬條,為性別建立索引是沒有必要的。相反,如果取值範圍很大,ca...
MySql的InnoDB儲存引擎 索引
索引分類 1 聚集索引 索引順序與物理順序一致。mysql 的 innodb 中,主鍵索引就是聚集索引。好處是,進行搜尋的時候,因為索引和物理順序一致,所以找資料的時候更快。2 非聚集索引 索引順序與物理順序不一致。非主鍵索引。在非主鍵索引中,又有組合索引 最左索引 也就是查詢的時候如果where條...
InnoDB引擎的索引和儲存結構
在oracle 和sql server等資料庫中只有一種儲存引擎,所有資料儲存管理機制都是一樣的。而mysql資料庫提供了多種儲存引擎。使用者可以根據不同的需求為資料表選擇不同的儲存引擎,使用者也可以根據自己的需要編寫自己的儲存引擎。mysql預設的儲存引擎是myisam,其他常用的就是innodb...