什麼是索引?
索引(在MySQL中也叫做“鍵”)是存儲引擎用於快速找到記錄的一種數據結構。索引存儲在文件系統中。索引的文件存儲形式與存儲引擎有關。
爲什麼索引可以加快查詢速度?
1.索引大大減少了服務器需要掃描的數據量。
2.索引可以幫助服務器避免排序和臨時表
3.索引可以將隨機I/O變爲順序I/O
哪些數據結構可以提高查詢速度,MySQL爲什麼使用B+樹?
1.hash表
缺點:① 利用hash存儲的話需要將所有的數據文件添加到內存,比較耗費內存空間
② 如果所有的查詢都是等值查詢,那麼hash確實很快,但是在企業或者實際工作環境中範圍查找的數據更多,而不是等 值查詢,因此hash就不太適合了
2. 二叉樹,紅黑樹
缺點:無論是二叉樹還是紅黑樹,都會因爲樹的深度過深而造成io次數變多,影響數據讀取效率
3.B-Tree
缺點:① 每個節點有key同時也有data,而每個頁存儲空間是有限的,如果data比較大的話會導致每個節點存儲的key數量變小 從而導致樹深增加。
② 當存儲的數據量很大時會導致樹的深度較大,增大查詢時磁盤io次數,進而影響查詢性能
B-Tree適用條件和限制
B-Tree對如下類型的查詢有效:全值匹配,匹配最左前綴,匹配列前綴,匹配範圍值,精確匹配某一列並範圍匹配另一列,只訪問索引的查詢(覆蓋索引)
B-Tree索引的限制:① 如果不是按照索引的最左列開始查找,則無法使用索引
② 不能跳過索引中的列
③ 如果查詢中有某個列的範圍查詢,則其右邊所有的列都無法使用索引
InnoDB和MyISAM區別
InnoDB | MyISAM | |
索引類型 | 聚簇索引 | 非聚簇索引 |
支持事務 | 是 | 否 |
支持表鎖 | 是 | 是 |
支持行鎖 | 是 | 否 |
支持外鍵 | 是 | 否 |
支持全文索引 | 5.6後支持 | 是 |
適合操作類型 | 大量增刪改 | 大量查 |
回表
在InnoDB中,有且僅有一個聚簇索引,這個聚簇索引是建立在主鍵上的(如果沒有主鍵,InnoDB會選擇一個唯一的非空索引替代,如果還沒有,則會隱式定義一個主鍵來作爲聚簇索引),聚簇索引在葉子節點保存數據。除了聚簇索引,還會有非聚簇索引(二級索引),二級索引的葉子節點保存的是主鍵值。所以二級索引在查找數據時,首先先查找非聚簇索引獲得主鍵值,再拿主鍵值去聚簇索引上查找數據,也就是經歷了兩次索引的查找。這個過程叫回表。如果還不懂去看這篇文章https://www.cnblogs.com/yanggb/p/11252966.html
覆蓋索引
索引覆蓋是一種避免回表查詢的優化策略。具體的做法就是將要查詢的數據作爲索引列建立普通索引(可以是單列索引,也可以一個索引語句定義所有要查詢的列,即聯合索引),這樣的話就可以直接返回索引中的的數據,不需要再通過聚集索引去定位行記錄,避免了回表的情況發生。
比如:表inventory有一個多列索引(store_id, film_id)。MySQL如果只需要訪問這兩個列,就可以使用這個索引做覆蓋索引
執行explain select store_id,film_id from inventory;
最左前綴匹配原則
在聯合索引中查找中,mysql會按照建立索引的列的順序,從左右向右依次找滿足條件的數據。
索引下推
“索引條件下推”,稱爲 Index Condition Pushdown (ICP)是mysql中一個常用的優化,尤其是當mysql需要從一張表裏檢索數據時。 如果沒有ICP,存儲引擎將會根據WHERE子句的條件遍歷整個表單數據,然後返回給mysql服務器。啓用ICP,如果可以通過使用索引的列來滿足WHERE條件,MySQL服務器將WHERE條件的這部分推送到存儲引擎。然後,存儲引擎通過使用索引來確定推送的條件,並且通過這樣的方式從表中讀取行。 ICP可以減少存儲引擎必須訪問基礎表的次數以及MySQL服務器必須訪問存儲引擎的次數。