日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

浅析聚簇索引与非聚簇索引(也叫二级索引)

發布時間:2024/2/28 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅析聚簇索引与非聚簇索引(也叫二级索引) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

通俗點講

  • 聚簇索引:將數據存儲與索引放到了一塊,找到索引也就找到了數據
  • 非聚簇索引:將數據存儲于索引分開結構,索引結構的葉子節點指向了數據的對應行,myisam通過key_buffer把索引先緩存到內存中,當需要訪問數據時(通過索引訪問數據),在內存中直接搜索索引,然后通過索引找到磁盤相應數據,這也就是為什么索引不在key buffer命中時,速度慢的原因

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

何時使用聚簇索引與非聚簇索引

cluster.png

聚簇索引具有唯一性

由于聚簇索引是將數據跟索引結構放到一塊,因此一個表僅有一個聚簇索引

一個誤區:把主鍵自動設為聚簇索引

聚簇索引默認是主鍵,如果表中沒有定義主鍵,InnoDB 會選擇一個唯一的非空索引代替。如果沒有這樣的索引,InnoDB 會隱式定義一個主鍵來作為聚簇索引。InnoDB 只聚集在同一個頁面中的記錄。包含相鄰健值的頁面可能相距甚遠。如果你已經設置了主鍵為聚簇索引,必須先刪除主鍵,然后添加我們想要的聚簇索引,最后恢復設置主鍵即可

此時其他索引只能被定義為非聚簇索引。這個是最大的誤區。有的主鍵還是無意義的自動增量字段,那樣的話Clustered index對效率的幫助,完全被浪費了。

剛才說到了,聚簇索引性能最好而且具有唯一性,所以非常珍貴,必須慎重設置。一般要根據這個表最常用的SQL查詢方式來進行選擇,某個字段作為聚簇索引,或組合聚簇索引,這個要看實際情況。

記住我們的最終目的就是在相同結果集情況下,盡可能減少邏輯IO

結合圖再仔細點看

image

image

  • InnoDB使用的是聚簇索引,將主鍵組織到一棵B+樹中,而行數據就儲存在葉子節點上,若使用"where id = 14"這樣的條件查找主鍵,則按照B+樹的檢索算法即可查找到對應的葉節點,之后獲得行數據
  • 對Name列進行條件搜索,則需要兩個步驟第一步在輔助索引B+樹中檢索Name,到達其葉子節點獲取對應的主鍵。第二步使用主鍵在主索引B+樹種再執行一次B+樹檢索操作,最終到達葉子節點即可獲取整行數據。(重點在于通過其他鍵需要建立輔助索引
  • MyISM使用的是非聚簇索引,非聚簇索引的兩棵B+樹看上去沒什么不同,節點的結構完全一致只是存儲的內容不同而已,主鍵索引B+樹的節點存儲了主鍵,輔助鍵索引B+樹存儲了輔助鍵。表數據存儲在獨立的地方,這兩顆B+樹的葉子節點都使用一個地址指向真正的表數據,對于表數據來說,這兩個鍵沒有任何差別。由于索引樹是獨立的,通過輔助鍵檢索無需訪問主鍵的索引樹

    聚簇索引的優勢

    看上去聚簇索引的效率明顯要低于非聚簇索引,因為每次使用輔助索引檢索都要經過兩次B+樹查找,這不是多此一舉嗎?聚簇索引的優勢在哪?

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

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

    所以建議使用int的auto_increment作為主鍵

    image

    主鍵的值是順序的,所以 InnoDB 把每一條記錄都存儲在上一條記錄的后面。當達到頁的最大填充因子時(InnoDB 默認的最大填充因子是頁大小的 15/16,留出部分空間用于以后修改),下一條記錄就會寫入新的頁中。一旦數據按照這種順序的方式加載,主鍵頁就會近似于被順序的記錄填滿(二級索引頁可能是不一樣的)

  • 如果主鍵比較大的話,那輔助索引將會變的更大,因為輔助索引的葉子存儲的是主鍵值;過長的主鍵值,會導致非葉子節點占用占用更多的物理空間
  • 為什么主鍵通常建議使用自增id

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

    因為MyISAM的主索引并非聚簇索引,那么他的數據的物理地址必然是凌亂的,拿到這些物理地址,按照合適的算法進行I/O讀取,于是開始不停的尋道不停的旋轉聚簇索引則只需一次I/O。(強烈的對比)

    不過,如果涉及到大數據量的排序、全表掃描、count之類的操作的話,還是MyISAM占優勢些,因為索引所占空間小,這些操作是需要在內存中完成的

    mysql中聚簇索引的設定

    聚簇索引默認是主鍵,如果表中沒有定義主鍵,InnoDB 會選擇一個唯一的非空索引代替。如果沒有這樣的索引,InnoDB 會隱式定義一個主鍵來作為聚簇索引。InnoDB 只聚集在同一個頁面中的記錄。包含相鄰健值的頁面可能相距甚遠。



    作者:kindol
    鏈接:https://www.jianshu.com/p/fa8192853184

    總結

    以上是生活随笔為你收集整理的浅析聚簇索引与非聚簇索引(也叫二级索引)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。