索引(index)是幫助mysql高效獲取資料的資料結構,這種資料結構是需要額外的寫入和儲存為代價來提高表上資料檢索的速度。一旦建立了索引後,資料庫中查詢優化器使用索引來快速定位資料,然後就無需掃瞄表中給定查詢的每一行了。索引本身也很大,不可能全部儲存在記憶體中,一般以索引檔案的形式儲存在磁碟上。
聚簇索引與非聚簇索引
當使用主鍵或唯一鍵建立表時,mysql會自動建立名為primary的特殊索引, 該索引稱為聚簇索引。primary索引是比較特殊的,這個索引本身與資料一起儲存在同乙個表中。聚簇索引表中的資料按主鍵的順序存放,它實際上就是按主鍵構建的乙個b+樹,葉子節點存放的是資料行記錄。所以資料庫中的資料實際上是索引的一部分。由於實際的資料頁只能按照乙個順序存放,所以每張表聚集索引只能有乙個。如果為表定義了乙個主鍵,mysql將使用主鍵作為聚簇索引;如果不為表指定乙個主鍵,mysql將第乙個組成列都not null的唯一索引作為聚簇索引;如果innobd表沒有主鍵且沒有適合的唯一索引(沒有構成該唯一索引的所有列都not null),mysql將自動建立乙個隱藏的名字為「gen_clust_index 」的聚簇索引。因此每個innodb表都有且僅有乙個聚簇索引。
非聚簇索引的葉子節點中存放的是鍵值和主鍵值,所以通過非聚集索引需要先查找到主鍵值然後通過聚集索引查詢到具體的資料,因此非聚集索引的效率要低於聚集索引。非聚集索引並不會影響到資料的儲存順序,所以非聚集索引可以存在多個。
索引原理
索引(index)是在儲存引擎(storage engine)層面實現的,而不是server層面。不是所有的儲存引擎都支援所有的索引型別。即使多個儲存引擎支援某一索引型別,它們的實現和行為也可能有所差別。myisam 和 innodb 儲存引擎,都使用 b+tree的資料結構,它相對與 b-tree結構,所有的資料都存放在葉子節點上,且把葉子節點通過指標連線到一起,形成了一條資料鏈表,以加快相鄰資料的檢索效率。
b-tree是為磁碟等外儲存裝置設計的一種平衡查詢樹。系統從磁碟讀取資料到記憶體時是以磁碟塊(block)為基本單位的,位於同乙個磁碟塊中的資料會被一次性讀取出來,而不是需要什麼取什麼。innodb 儲存引擎中有頁(page)的概念,頁是其磁碟管理的最小單位。innodb 儲存引擎中預設每個頁的大小為16kb,可通過引數 innodb_page_size 將頁的大小設定為 4k、8k、16k,在 mysql 中可通過如下命令檢視頁的大小:show variables like 'innodb_page_size'。而系統乙個磁碟塊的儲存空間往往沒有這麼大,因此 innodb 每次申請磁碟空間時都會是若干位址連續磁碟塊來達到頁的大小 16kb。innodb 在把磁碟資料讀入到磁碟時會以頁為基本單位,在查詢資料時如果乙個頁中的每條資料都能有助於定位資料記錄的位置,這將會減少磁碟i/o次數,提高查詢效率。
【b樹】
b-tree 結構的資料可以讓系統高效的找到資料所在的磁碟塊。為了描述 b-tree,首先定義一條記錄為乙個二元組[key, data] ,key為記錄的鍵值,對應表中的主鍵值,data 為一行記錄中除主鍵外的資料。對於不同的記錄,key值互不相同。
模擬查詢關鍵字29個過程:
1.根據根節點找到磁碟塊1,讀入記憶體。【磁碟i/o操作第1次】
2.比較關鍵字29在區間(17,35),找到磁碟塊1的指標p2。
3.根據p2指標找到磁碟塊3,讀入記憶體。【磁碟i/o操作第2次】
4.比較關鍵字29在區間(26,30),找到磁碟塊3的指標p2。
5.根據p2指標找到磁碟塊8,讀入記憶體。【磁碟i/o操作第3次】
6.在磁碟塊8中的關鍵字列表中找到關鍵字29。
【b+樹】
b+tree 是在 b-tree 基礎上的一種優化,使其更適合實現外儲存索引結構,innodb 儲存引擎就是用 b+tree 實現其索引結構。
b+樹特徵:
1.非葉子結點中的關鍵字不儲存資料,只用來索引,所有資料都儲存在葉子節點(b樹是每個關鍵字都儲存資料)。
2.所有的葉子節點包含了全部關鍵字資訊,以及指向這些關鍵字記錄的指標,且葉子節點本身依關鍵字的大小自小而大順序鏈結
3.所有的非葉子節點可以看成是索引部分,節點中僅含有其子樹的最大(或最小關鍵字)
4.通常b+樹上有兩個頭指標,乙個指向根節點,乙個指向關鍵字最小的葉子節點
【總結】
b+樹的優點在於:
1.由於b+樹在內部節點上不包含資料資訊,因此在記憶體頁中能夠存放更多的key。 資料存放的更加緊密,具有更好的空間區域性性。因此訪問葉子節點上關聯的資料也具有更好的快取命中率。
2.b+樹的葉子結點都是相鏈的,因此對整棵樹的便利只需要一次線性遍歷葉子結點即可。而且由於資料順序排列並且相連,所以便於區間查詢和搜尋。而b樹則需要進行每一層的遞迴遍歷,相鄰的元素可能在記憶體中不相鄰,所以快取命中性沒有b+樹好。
b樹的優點在於:
1.由於b樹的每乙個節點都包含key和value,因此經常訪問的元素可能離根節點更近,因此訪問也更迅速。
索引失效
1、like 以%開頭,索引無效;當like字首沒有%,字尾有%時,索引有效。
2、如果條件中有or,即使其中有條件帶索引也不會使用(這也是為什麼盡量少用or的原因).要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引
3、組合索引,不是使用第一列索引,索引失效。
4、資料型別出現隱式轉化。如varchar不加單引號的話可能會自動轉換為int型,使索引無效,產生全表掃瞄。
5、在索引欄位上使用not,<>,!=。不等於操作符是永遠不會用到索引的,因此對它的處理只會產生全表掃瞄。 優化方法: key<>0 改為 key>0 or key<0。
6、對索引字段進行計算操作、欄位上使用函式。(索引為 emp(ename,empno,sal))
7、當全表掃瞄速度比索引速度快時,mysql會使用全表掃瞄,此時索引失效。
mysql各種索引名稱 MySQL索引型別大彙總
本文主要介紹了7種不同型別的mysql索引型別。在mysql資料庫表中,對欄位進行建立索引是可以大幅度的提高其實際查詢速度。通過對這些索引的巧妙的運用,我們可以令mysql的查詢和執行更加高效。索引是快速搜尋的關鍵。mysql索引的建立對於mysql的高效執行是很重要的。下面介紹幾種常見的mysql...
mysql 索引 手冊 MySQL 索引
mysql 索引 mysql索引的建立對於mysql的高效執行是很重要的,索引可以大大提高mysql的檢索速度。打個比方,如果合理的設計且使用索引的mysql是一輛蘭博基尼的話,那麼沒有設計和使用索引的mysql就是乙個人力三輪車。索引分單列索引和組合索引。單列索引,即乙個索引只包含單個列,乙個表可...
mysql非同步索引 MySQL索引
一 為什麼要使用索引 優化查詢,減少掃瞄的錶行數。打個比方,索引的作用就和查新華字典,字典的索引的作用的一樣的。二 索引的型別 1 索引是在儲存引擎中實現的,而不是在伺服器層中實現的。所以,每種儲存引擎的索引都不一定完全相同,並不是所有的儲存引擎都支援所有的索引型別。2 如果使用的是組合索引 即有多...