MySQL之 索引

1、聚簇索引和非聚簇索引的區別?

  • 聚簇索引:將數據存儲與索引放到了一塊,索引結構的葉子節點保存了行數據
  • 非聚簇索引:將數據與索引分開存儲,索引結構的葉子節點指向了數據對應的位置

       在innodb中,在聚簇索引之上創建的索引稱之爲輔助索引,非聚簇索引都是輔助索引,像複合索引、前綴索引、唯一索引。輔助索引葉子節點存儲的不再是行的物理位置,而是主鍵值,輔助索引訪問數據總是需要二次查找

圖1 innoDB表分佈

(1) 聚簇索引將主鍵組織到一棵B+樹中,而行數據就儲存在葉子節點上,若使用"where id = 14"這樣的條件查找主鍵,則按照B+樹的檢索算法即可查找到對應的葉節點,之後獲得行數據

(2)對Name列進行條件搜索,則需要兩個步驟第一步在輔助索引B+樹中檢索Name,到達其葉子節點獲取對應的主鍵。第二步使用主鍵在主索引B+樹種再執行一次B+樹檢索操作,最終到達葉子節點即可獲取整行數據

聚簇索引的優勢:

  1. 由於行數據和葉子節點存儲在一起,同一頁中會有多條行數據,訪問同一數據頁不同行記錄時,已經把頁加載到了Buffer中,再次訪問的時候,會在內存中完成訪問,不必訪問磁盤。這樣主鍵和行數據是一起被載入內存的,找到葉子節點就可以立刻將行數據返回了,如果按照主鍵Id來組織數據,獲得數據更快
  2. 輔助索引使用主鍵作爲"指針"而不是使用地址值作爲指針的好處是,減少了當出現行移動或者數據頁分裂時輔助索引的維護工作使用主鍵值當作指針會讓輔助索引佔用更多的空間,換來的好處是InnoDB在移動行時無須更新輔助索引中的這個"指針"也就是說行的位置(實現中通過16K的Page來定位)會隨着數據庫裏數據的修改而發生變化(前面的B+樹節點分裂以及Page的分裂),使用聚簇索引就可以保證不管這個主鍵B+樹的節點如何變化,輔助索引樹都不受影響
  3. 聚簇索引適合用在排序的場合,非聚簇索引不適合
  4. 取出一定範圍數據的時候,使用用聚簇索引
  5. 二級索引需要兩次索引查找,而不是一次才能取到數據,因爲存儲引擎第一次需要通過二級索引找到索引的葉子節點,從而找到數據的主鍵,然後在聚簇索引中用主鍵再次查找索引,再找到數據
  6. 可以把相關數據保存在一起。例如實現電子郵箱時,可以根據用戶 ID 來聚集數據,這樣只需要從磁盤讀取少數的數據頁就能獲取某個用戶的全部郵件。如果沒有使用聚簇索引,則每封郵件都可能導致一次磁盤 I/O。

聚簇索引的劣勢:

  1. 維護索引很昂貴,特別是插入新行或者主鍵被更新導至要分頁(page split)的時候。建議在大量插入新行後,選在負載較低的時間段,通過OPTIMIZE TABLE優化表,因爲必須被移動的行數據可能造成碎片。使用獨享表空間可以弱化碎片
  2. 表因爲使用UUId(隨機ID)作爲主鍵,使數據存儲稀疏,這就會出現聚簇索引有可能有比全表掃面更慢,

2、聚簇索引需要注意的地方?

      當使用主鍵爲聚簇索引時,主鍵最好不要使用uuid,因爲uuid的值太過離散,不適合排序且可能出線新增加記錄的uuid,會插入在索引樹中間的位置,導致索引樹調整複雜度變大,消耗更多的時間和資源

      建議使用int類型的自增,方便排序並且默認會在索引樹的末尾增加主鍵值,對索引樹的結構影響最小。而且,主鍵值佔用的存儲空間越大,輔助索引中保存的主鍵值也會跟着變大,佔用存儲空間,也會影響到IO操作讀取到的數據量。

3、爲什麼主鍵通常建議使用自增id?

       聚簇索引的數據的物理存放順序與索引順序是一致的,即:只要索引是相鄰的,那麼對應的數據一定也是相鄰地存放在磁盤上的。如果主鍵不是自增id,那麼可以想 象,它會幹些什麼,不斷地調整數據的物理地址、分頁,當然也有其他一些措施來減少這些操作,但卻無法徹底避免。但,如果是自增的,那就簡單了,它只需要一 頁一頁地寫,索引結構相對緊湊,磁盤碎片少,效率也高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章