澄清一個概念:innodb中,在聚簇索引之上建立的索引稱之爲輔助索引,輔助索引訪問數據老是須要二次查找,非聚簇索引都是輔助索引,像複合索引、前綴索引、惟一索引,輔助索引葉子節點存儲的再也不是行的物理位置,而是主鍵值mysql
cluster.png算法
因爲聚簇索引是將數據跟索引結構放到一塊,所以一個表僅有一個聚簇索引sql
聚簇索引默認是主鍵,若是表中沒有定義主鍵,InnoDB 會選擇一個惟一的非空索引代替。若是沒有這樣的索引,InnoDB 會隱式定義一個主鍵來做爲聚簇索引。InnoDB 只彙集在同一個頁面中的記錄。包含相鄰健值的頁面可能相距甚遠。若是你已經設置了主鍵爲聚簇索引,必須先刪除主鍵,而後添加咱們想要的聚簇索引,最後恢復設置主鍵便可。數據庫
此時其餘索引只能被定義爲非聚簇索引。這個是最大的誤區。有的主鍵仍是無心義的自動增量字段,那樣的話Clustered index對效率的幫助,徹底被浪費了。緩存
剛纔說到了,聚簇索引性能最好並且具備惟一性,因此很是珍貴,必須慎重設置。通常要根據這個表最經常使用的SQL查詢方式來進行選擇,某個字段做爲聚簇索引,或組合聚簇索引,這個要看實際狀況。性能
記住咱們的最終目的就是在相同結果集狀況下,儘量減小邏輯IO。大數據
image優化
imagespa
MyISM使用的是非聚簇索引,非聚簇索引的兩棵B+樹看上去沒什麼不一樣,節點的結構徹底一致只是存儲的內容不一樣而已,主鍵索引B+樹的節點存儲了主鍵,輔助鍵索引B+樹存儲了輔助鍵。表數據存儲在獨立的地方,這兩顆B+樹的葉子節點都使用一個地址指向真正的表數據,對於表數據來講,這兩個鍵沒有任何差異。因爲索引樹是獨立的,經過輔助鍵檢索無需訪問主鍵的索引樹。3d
看上去聚簇索引的效率明顯要低於非聚簇索引,由於每次使用輔助索引檢索都要通過兩次B+樹查找,這不是畫蛇添足嗎?聚簇索引的優點在哪?
image
因此建議使用int的auto_increment做爲主鍵
image
主鍵的值是順序的,因此 InnoDB 把每一條記錄都存儲在上一條記錄的後面。當達到頁的最大填充因子時(InnoDB 默認的最大填充因子是頁大小的 15/16,留出部分空間用於之後修改),下一條記錄就會寫入新的頁中。一旦數據按照這種順序的方式加載,主鍵頁就會近似於被順序的記錄填滿(二級索引頁多是不同的)
聚簇索引的數據的物理存放順序與索引順序是一致的,即:只要索引是相鄰的,那麼對應的數據必定也是相鄰地存放在磁盤上的。若是主鍵不是自增id,那麼能夠想 象,它會幹些什麼,不斷地調整數據的物理地址、分頁,固然也有其餘一些措施來減小這些操做,但卻沒法完全避免。但,若是是自增的,那就簡單了,它只須要一 頁一頁地寫,索引結構相對緊湊,磁盤碎片少,效率也高。
由於MyISAM的主索引並不是聚簇索引,那麼他的數據的物理地址必然是凌亂的,拿到這些物理地址,按照合適的算法進行I/O讀取,因而開始不停的尋道不停的旋轉。聚簇索引則只需一次I/O。(強烈的對比)
不過,若是涉及到大數據量的排序、全表掃描、count之類的操做的話,仍是MyISAM佔優點些,由於索引所佔空間小,這些操做是須要在內存中完成的。
聚簇索引默認是主鍵,若是表中沒有定義主鍵,InnoDB 會選擇一個惟一的非空索引代替。若是沒有這樣的索引,InnoDB 會隱式定義一個主鍵來做爲聚簇索引。InnoDB 只彙集在同一個頁面中的記錄。包含相鄰健值的頁面可能相距甚遠。