聚簇索引:將數據存儲與索引放到了一塊,索引結構的葉子節點保存了行數據算法
非聚簇索引:將數據與索引分開存儲,索引結構的葉子節點指向了數據對應的位置緩存
在innodb中,在聚簇索引之上建立的索引稱之爲輔助索引,非聚簇索引都是輔助索引,像複合索引、前綴索引、惟一索引。輔助索引葉子節點存儲的再也不是行的物理位置,而是主鍵值,輔助索引訪問數據老是須要二次查找。oracle
聚簇索引具備惟一性,因爲聚簇索引是將數據跟索引結構放到一塊,所以一個表僅有一個聚簇索引。大數據
表中行的物理順序和索引中行的物理順序是相同的,在建立任何非聚簇索引以前建立聚簇索引,這是由於聚簇索引改變了表中行的物理順序,數據行 按照必定的順序排列,而且自動維護這個順序;ui
聚簇索引默認是主鍵,若是表中沒有定義主鍵,InnoDB 會選擇一個惟一且非空的索引代替。若是沒有這樣的索引,InnoDB 會隱式定義一個主鍵(相似oracle中的RowId)來做爲聚簇索引。若是已經設置了主鍵爲聚簇索引又但願再單獨設置聚簇索引,必須先刪除主鍵,而後添加咱們想要的聚簇索引,最後恢復設置主鍵便可。blog
MyISAM使用的是非聚簇索引,非聚簇索引的兩棵B+樹看上去沒什麼不一樣,節點的結構徹底一致只是存儲的內容不一樣而已,主鍵索引B+樹的節點存儲了主鍵,輔助鍵索引B+樹存儲了輔助鍵。表數據存儲在獨立的地方,這兩顆B+樹的葉子節點都使用一個地址指向真正的表數據,對於表數據來講,這兩個鍵沒有任何差異。因爲索引樹是獨立的,經過輔助鍵檢索無需訪問主鍵的索引樹。排序
使用聚簇索引的優點:索引
每次使用輔助索引檢索都要通過兩次B+樹查找,看上去聚簇索引的效率明顯要低於非聚簇索引,這不是畫蛇添足嗎?聚簇索引的優點在哪?內存
1.因爲行數據和聚簇索引的葉子節點存儲在一塊兒,同一頁中會有多條行數據,訪問同一數據頁不一樣行記錄時,已經把頁加載到了Buffer中(緩存器),再次訪問時,會在內存中完成訪問,沒必要訪問磁盤。這樣主鍵和行數據是一塊兒被載入內存的,找到葉子節點就能夠馬上將行數據返回了,若是按照主鍵Id來組織數據,得到數據更快。資源
2.輔助索引的葉子節點,存儲主鍵值,而不是數據的存放地址。好處是當行數據放生變化時,索引樹的節點也須要分裂變化;或者是咱們須要查找的數據,在上一次IO讀寫的緩存中沒有,須要發生一次新的IO操做時,能夠避免對輔助索引的維護工做,只須要維護聚簇索引樹就行了。另外一個好處是,由於輔助索引存放的是主鍵值,減小了輔助索引佔用的存儲空間大小。
注:咱們知道一次io讀寫,能夠獲取到16K大小的資源,咱們稱之爲讀取到的數據區域爲Page。而咱們的B樹,B+樹的索引結構,葉子節點上存放好多個關鍵字(索引值)和對應的數據,都會在一次IO操做中被讀取到緩存中,因此在訪問同一個頁中的不一樣記錄時,會在內存裏操做,而不用再次進行IO操做了。除非發生了頁的分裂,即要查詢的行數據不在上次IO操做的換村裏,纔會觸發新的IO操做。
3.由於MyISAM的主索引並不是聚簇索引,那麼他的數據的物理地址必然是凌亂的,拿到這些物理地址,按照合適的算法進行I/O讀取,因而開始不停的尋道不停的旋轉。聚簇索引則只需一次I/O。(強烈的對比)
4.不過,若是涉及到大數據量的排序、全表掃描、count之類的操做的話,仍是MyISAM佔優點些,由於索引所佔空間小,這些操做是須要在內存中完成的。
聚簇索引須要注意的地方
當使用主鍵爲聚簇索引時,主鍵最好不要使用uuid,由於uuid的值太過離散,不適合排序且可能出線新增長記錄的uuid,會插入在索引樹中間的位置,致使索引樹調整複雜度變大,消耗更多的時間和資源。
建議使用int類型的自增,方便排序而且默認會在索引樹的末尾增長主鍵值,對索引樹的結構影響最小。並且,主鍵值佔用的存儲空間越大,輔助索引中保存的主鍵值也會跟着變大,佔用存儲空間,也會影響到IO操做讀取到的數據量。
爲何主鍵一般建議使用自增id
聚簇索引的數據的物理存放順序與索引順序是一致的,即:只要索引是相鄰的,那麼對應的數據必定也是相鄰地存放在磁盤上的。若是主鍵不是自增id,那麼能夠想 象,它會幹些什麼,不斷地調整數據的物理地址、分頁,固然也有其餘一些措施來減小這些操做,但卻沒法完全避免。但,若是是自增的,那就簡單了,它只須要一 頁一頁地寫,索引結構相對緊湊,磁盤碎片少,效率也高。
轉載: