索引是什麼
索引是爲了加速對錶中數據行的檢索而建立的一種分散存儲的數據結構 解釋:索引和數據都是存在磁盤的,須要把數據拿到內存中進行比較查找到對應的數據,若是沒有用索引,就會從磁盤全盤掃描,若是走索引,他會經過索引找到對應的數據位置,從而直接去取數據 mysql
爲何要用索引
索引能極大的減小存儲引擎須要掃描的數據量
索引能夠把隨機IO變成順序IO
索引能夠幫助咱們在進行分組、排序等操做時,避免使用臨時表
爲何是B+Tree
二叉樹
平衡二叉樹
缺點:
層級太深 層級的深度決定了他的IO操做次數,IO操做耗時大
每個節點數據太少 沒有很好的利用操做磁盤IO的數據交換特性,也沒有利用好磁盤IO的預讀能力(空間局部性原理),從而帶來頻繁的IO操做
解釋:查找從根節點開始,一次比較就須要把一個節點數據加載到內存中進行判斷(一次IO),因此層級越深,比較和IO次數就越多。 預讀:每一次IO時,不單單把當前磁盤地址的數據加載到內存,同時也把相鄰數據也加載到內存緩衝區中。當訪問一個地址數據的時候,與其相鄰的數據很快也會被訪問到。每次磁盤IO讀取的數據咱們稱之爲一頁(page)。一頁的大小與操做系統有關,通常爲4k或者8k。這也就意味着讀取一頁內數據的時候,實際上發生了一次磁盤IO,mysql爲16Ksql
多路平衡查找樹 B-Tree
解釋:
多路:節點的子節點最多的個數
關鍵字個數=路數-1
好處:隨着路數的增多,能夠存儲更多的數據,層級也會變得更短,這樣就減小了IO操做
Mysql的B+Tree
B+Tree與B-Tree的區別
B+節點關鍵字搜索採用閉合區間
B+非葉子節點不保存數據相關信息,只保存關鍵字和子節點的引用
B+關鍵字對應的數據保存在葉子節點中
B+葉子節點是順序排列的,而且相鄰節點具備順序引用的關係
爲何選用B+Tree
B+樹是B-樹的變種,他包含B-樹的優點
B+樹掃庫、表能力更強(覆蓋索引若是要掃庫或者掃表的話(什麼是覆蓋索引,後面會說)B-樹要掃描樹全部節點,B+樹只要掃描葉子節點)
B+樹的磁盤讀寫能力更強(由於非葉子節點不存數據,因此每頁存儲的關鍵字會更多,路數會更多)
B+樹的排序能力更強
B+樹的查詢效率更加穩定(B+樹永遠要找到葉子節點,由於數據是存在葉子節點,因此IO次數是必定的,B-樹找到節點就能夠返回,同一個樹不一樣數據IO次數是不同的)
Mysql B+Tree索引體現形式
Mysql有不少存儲引擎,建立表的時候指定對應的存儲引擎,經常使用的是Myisam和Innodb,默認爲Innodb數據庫
Myisam索引
Myisam建立表的時候會有三個文件:.frm文件(表定義文件)、.MYD文件(數據)、.MYI文件(索引)數據結構
葉子節點存儲的是數據對應的地址
InnoDB索引
InnoDB建立表的時候只有兩個文件:.frm文件(表定義文件)、.idb文件(數據) 索引和數據放在一塊兒性能
解釋:
InnoDB都會以主鍵爲索引來組織數據的存儲,若是沒有指定主鍵,它會定義一個隱藏的默認的主鍵索引ui
彙集索引:指索引項的排序方式和表中數據記錄排序方式一致的索引操作系統
聚簇索引:聚簇索引並非一種單獨的索引類型,而是一種數據存儲方式。術語「聚族」表示數據行和相鄰的鍵值緊湊的存儲在一塊兒。由於沒法同時把數據行放在兩個不一樣的地方,因此一個表只能有一個聚族索引3d
因此InnoDB主鍵索引既是彙集索引也是聚簇索引cdn
輔助索引:除了主鍵索引以外的索引 blog
從圖能夠看出,輔助索引葉子節點保存的是主鍵索引的值
Innodb vs Myisam
總結:Innodb輔助索引葉子節點爲何不直接保存數據地址 而是保存主鍵值呢,這樣還要經過主鍵再去查一遍索引,保存主鍵的緣由是由於他們首先認爲主鍵索引是最經常使用的索引,其次就是通常主鍵是不會變的,改變其餘值,輔助索引就不須要改動了
索引的其餘補充
列的離散性:離散性越高選擇性就越好
最左匹配原則:對索引中關鍵字進行對比,必定是從左往右依次進行,且不可跳過
聯合索引:節點中關鍵字是多個,單列索引是特殊的聯合索引。舉例a,b,c三列上建立一個聯合索引,create index abc on users(a,b,c) 通常會問哪些會走索引,走什麼索引,a、a,b、a,b,c、a,c(走a列,c列是不走索引的)會走索引,b,b,c,c是不走索引的,根據最左匹配原則,必定是從左開始的,abc列值會在節點中從左到右順序排列的
覆蓋索引:若是查詢列可經過索引節點中的關鍵字直接返回,則該索引稱爲覆蓋索引,覆蓋索引可減小數據庫IO,可提升查詢性能,由於查索引就能夠直接返回了,因此通常查詢最少列
索引列的數據長度能少則少
主鍵爲何建議用int 自增加 而不用uuid緣由:1.uuid長度比int長,因此用int,節點存儲的關鍵字會更多,路數會比uuid多,層級會更短。2.主鍵通常是不變的,順序自增加,uuid是不定的,當增長數據時,自增加樹的改動會遠遠比uuid的改動下
索引不是越多越好,越全越好,由於索引是須要維護的,多了也會影響性能