MySQL是我們經常使用到的數據庫,因為很多時候是免費的,所以用的比較多,我們在設計表的時候應該會使用到索引,所以我們一起來聊下索引應該怎么去設置
1、索引的定義
什么叫索引 ,索引是幫助Mysql高效獲取數據的數據結構(有序),在數據之外,數據庫系統還維護著滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找算法,這種數據結構就是索引,如圖所示
索引本身也很大,不可能全部存儲在內存中,因此索引往往以索引文件的形式存儲在磁盤上索引是數據庫中用來提高性能的最常用工具。
索引的優勢:1)類似于書籍中的目錄索引,提高數據檢索的效率,降低數據庫中的IO成本 2)通過索引列對數據進行排序,降低數據排序的成本,降低CPU的消耗
索引的劣勢:1)實際上索引也是一張表,該表中保存了主鍵和索引字段,并指向實體類的記錄,所以索引列也是要占用空間的。
2)雖然索引大大提高了查詢效率,同時卻也降低更新表的速度,如對表進行insert、update、delete。因為更新表時,MySQL不僅要保存數據,還要保存一下索引文件每次更新添加了索引列的字段,都會調整因為更新所帶來的鍵值變化后的索引信息
2、存儲引擎對各種索引類型的支持
平常所說的索引,若沒有特別指明,都是指B+數(多路搜索樹,并不一定是二又的)結構組織的所有。其中聚集索引、非聚集索引( 普通索引,前綴索引、唯一索引,全文索引)默認都是使用B+tree樹索引,統稱為索引。
3、Btree結構
Btree又叫多路平衡搜索樹,一顆m又的Btree特性如下樹中每個節點最多包含M個孩子除根節點和葉子節點外,每個節點至少有ceil(m/2)個孩子若根節點不是葉子節點,則至少有兩個孩子。所有的葉子節點都在同一層。
每個非葉子節點有n個key與n+1個指針組成,其中[ceil(m/2)-1]<=n<=m-1。
以5叉Btree為例,key的數量:工時推導[ceil(m/2)-1]<n<=m-1。所以2<=n<n<=4。當n>4時,
中間節點分裂到父子節點,兩邊節點分裂。
插入CNGAHEKOMFWLTZDPRXYS數據為例。
到此,該Btree樹就已經構建完成了,Btree樹和二叉樹相比,查詢數據的效率更高,因為相同的數據量來說,Btree的層級結構比二叉樹小,因此搜索速度快
B+tree為Btree的變種,B+tree與Btree的區別為:
1)n又B+tree最多包含n個key,而Btree最多包含n-1個key
2)B+tree的葉子節點保存所有的key信息,依key大小順序排列
3)所有的非葉子節點都可以看做是key的索引部分。
由于B+tree只有葉子節點保存key信息,查詢任何key都要從root走到葉子,所以B+tree的查詢效率更加穩定
Mysql索引數據結構對經典的B+bree進行了優化,在原B+Tree的基礎上,增加一個指向相鄰葉子節點的鏈表指針,就形成了帶有順序指針的B+bree,提高區間訪問性能。
4、索引的種類
- 聚集索引
- 非聚集索引(輔助索引、二級索)
CREATE TABLEmerchandiseidint(11)NOT NULLserial no varchar(20) DEFAULT NULLname varchar(255)DEFAULT NULL.unit_price decimal(10, 2) DEFAULT NULLPRIMARY KEY Cid)USING BTREECHARACTER SET = utf8 COLLATE =utf8_general_ci ROW_FORMAT = Dynamic;
非聚集索引
MyISAM 使用的是輔助索引,索引中每一個葉子節點僅僅記錄的是每行數據的物理地址,即行指針
聚集索引
Inndb主鍵索引是聚簇索引,其葉子節點則記錄了主鍵值事務id、用于事務和MVCC的回流指針以及所有的剩余列,其他非主鍵索引是非聚集索引
5、MySQL的索引-設計原則
- 對查詢頻次較高,且數據量比較大的表建立索引。
- 索引字段的選擇,最佳候選列應當從where子句的條件中提取,如果where子句的組合比較多,那么應當選擇最常用、過濾效果最好的列的組合
- 使用唯一索引,區分越高,使用索引的效率越高。
- 索引可以有效提升查詢數據庫的效率,但是索引數量不是多多益善,索引越多,維護索引的代,價自然也就水漲船高。對于插入、更新、刪除等DML操作比較頻繁的表來說,索引過多,會映入相當高的維護代價,境地DML操作的效率,增加相應操作的時間消耗。另外索引過多的話MySQL也會犯選擇困難病,雖然最終仍然會找到一個可用的索引,但無疑提交了選擇的代價
- 使用短索引,索引創建之后也是使用硬盤來存儲,因此提升索引訪問的I/0效率,也可以提升總體的訪問效率。假如構成索引的字段總長度比較短,那么在給定大小的存儲塊內可以以存儲更多的索引值,相對應的可以有效的提升MySOL訪問索引的I/O效率
- 利用最左前綴,N個列組合而成的組合索引,那么相當于是創建了N個索引,如果查詢時where子句中使用了組成該索引的前幾個字段,那么這條查詢SOL可以利用組合索引來提高查詢效率