有哪些索引,怎麼分類?
mysql 中的儲存引擎和索引
為什麼使用b-tree/b+tree做為索引的資料結構
索引,就是幫助我們快速獲取訪問資料庫中表的資訊。比如一本沒有目錄的書,和有一本有目錄的書,自己想想吧。
怎麼實現的呢? 在乙個沒有結構無序的資料中查詢(沒有資料結構),怎麼建立索引???—— 只有掃瞄整個表
當然,建立索引肯定是基於某種資料結構上的,我們每次更新,刪除,插入,都要去維護這個資料結構,才能幫助我們快速訪問資料庫中表的資訊。就拿上面目錄的列子,你在書中改了某些內容,不更新目錄怎麼行??
所以:索引的實現通常使用b樹及其變種b+樹
全是好處,那不豈不是每個表都來乙個索引??反過來想一下,建立索引不需要維護和額外的空間嗎?
主鍵就是唯一索引,但是唯一索引不一定是主鍵,唯一索引可以為空,但是空值只能有乙個,主鍵不能為空。
普通唯一索引:單個欄位上建立唯一索引,需要此欄位所在的列上不能有重複的值,屬於二級索引。
復合唯一索引:多個欄位上聯合建立唯一索引,屬於二級索引。對於mysql儲存引擎來說,innodb 主要使用的是聚簇索引,myisam 不管是主鍵索引還是二級索引都是使用的非聚簇索引。
非聚簇索引:記錄的物理順序與邏輯順序沒有必然的聯絡,與資料的儲存物理結構沒有關係;乙個表對應的非聚簇索引可以有多條,根據不同列的約束可以建立不同要求的非聚簇索引;
資料庫中索引的優缺點
聚簇索引與非聚簇索引
通過查詢索引就能確定最終的資料,不用再利用葉子節點中儲存的主鍵值去查詢對應的資料。
覆蓋索引的效能是極高的。
所謂全文索引,是一種通過建立倒排索引,快速匹配文件的方式。
tips:
innodb引擎對fulltext索引的支援是mysql5.6新引入的特性,之前只有myisam引擎支援fulltext索引。對於fulltext索引的內容可以使用match(column)…against(val)語法進行查詢。
在 mysql 中,主要有四種型別的索引,分別為: b-tree 索引, hash 索引, fulltext 索引和 r-tree 索引。我們主要分析b-tree 索引。
一般來說, mysql 中的 b-tree 索引的物理檔案大多都是以 balance tree 的結構來儲存的,也就是所有實際需要的資料都存放於 tree 的 leaf node(葉子節點) ,而且到任何乙個 leaf node 的最短路徑的長度都是完全相同的,所以我們大家都稱之為 b-tree 索引。
當然,可能各種資料庫(或 mysql 的各種儲存引擎)在存放自己的 b-tree 索引的時候會對儲存結構稍作改造。
如innodb 儲存引擎的 b-tree 索引實際使用的儲存結構實際上是 b+tree,也就是在 b-tree 資料結構的基礎上做了很小的改造,在每乙個leaf node 上面出了存放索引鍵的相關資訊之外,還儲存了指向與該 leaf node 相鄰的後乙個 leafnode 的指標資訊(增加了順序訪問指標),這主要是為了加快檢索多個相鄰 leaf node 的效率考慮。
myisam和innodb兩個儲存引擎的索引實現方式:
這也涉及到上文所說的,在myisam索引中主要採用的是非聚簇索引,myisam引擎使用b+tree作為索引結構,葉節點的data域存放的是資料記錄的位址。下圖是myisam主鍵索引的原理圖:
這裡設表一共有三列,假設我們以col1為主鍵,是乙個myisam表的主索引(primary key)示意。可以看出myisam的索引檔案僅僅儲存資料記錄的位址。
在myisam中,主索引和二級索引(secondary key)在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重複。如果我們在col2上建立乙個輔助索引,則此索引的結構如下圖所示:
myisam中索引檢索的演算法為首先按照b+tree搜尋演算法搜尋索引,如果指定的key存在,則取出其data域的值,然後以data域的值為位址,讀取相應資料記錄。
innodb也使用b+tree作為索引結構,但其採用聚簇索引的實現方式,索引於myisam完全不同
innodb的所有二級索引都引用主鍵作為data域。例如,下圖為定義在col3上的乙個二級索引:
innodb 表是基於聚簇索引建立的。因此innodb 的索引能提供一種非常快速的主鍵查詢效能。不過,它的二級索引(secondary index, 也就是非主鍵索引)也會包含主鍵列,所以,如果主鍵定義的比較大,其他索引也將很大。如果想在表上定義 、很多索引,則爭取盡量把主鍵定義得小一些。innodb 不會壓縮索引。
文字元的ascii碼作為比較準則。聚集索引這種實現方式使得按主鍵的搜尋十分高效,但是二級索引搜尋需要檢索兩遍索引:首先檢索二級索引獲得主鍵,然後用主鍵到主索引中檢索獲得記錄。
所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大
因為innodb資料檔案本身是一顆b+tree,非單調的主鍵會造成在插入新記錄時資料檔案為了維持b+tree的特性而頻繁的**調整,十分低效,而使用自增字段作為主鍵則是乙個很好的選擇。
平衡樹(balance tree)還有紅黑樹等資料結構也可以用來實現索引,但是檔案系統及資料庫系統普遍採用b-/+tree作為索引結構。
一般來說,索引本身也很大,不可能全部儲存在記憶體中,因此索引往往以索引檔案的形式儲存的磁碟上。這樣的話,索引查詢過程中就要產生磁碟i/o消耗,相對於記憶體訪問,i/o訪問的消耗要高幾個數量級,所以評價乙個資料結構作為索引的優劣最重要的指標就是在查詢過程中磁碟i/o操作次數的漸進複雜度。換句話說,索引的結構組織要儘量減少查詢過程中磁碟i/o的訪問次數。為什麼使用b-/+tree,還跟磁碟訪問原理有關。
磁碟本身訪問就比主存慢很多,再加上機械運動耗費,磁碟的訪問速度往往是主存的幾百分分之一,因此為了提高效率,要儘量減少磁碟i/o。為了達到這個目的,磁碟往往不是嚴格按需讀取,而是每次都會預讀,即使只需要乙個位元組,磁碟也會從這個位置開始,順序向後讀取一定長度的資料放入記憶體。這樣做的理論依據是電腦科學中著名的區域性性原理:
預讀的長度一般為頁(page)的整倍數。頁是計算機管理儲存器的邏輯塊,硬體及作業系統往往將主存和磁碟儲存區分割為連續的大小相等的塊,每個儲存塊稱為一頁(在許多作業系統中,頁得大小通常為4k),主存和磁碟以頁為單位交換資料。
當程式要讀取的資料不在主存中時,會觸發乙個缺頁異常,此時系統會向磁碟發出讀盤訊號,磁碟會找到資料的起始位置並向後連續讀取一頁或幾頁載入記憶體中,然後異常返回,程式繼續執行。
我們上面分析b-/+tree檢索一次最多需要訪問節點:
h =l
ogm2
(n+1
2)+1
h =log_\frac(\frac)+1
h=log2
m(
2n+1
)+1
資料庫系統巧妙利用了磁碟預讀原理,將乙個節點的大小設為等於乙個頁,這樣每個節點只需要一次i/o就可以完全載入。為了達到這個目的,在實際實現b- tree還需要使用如下技巧:
綜上所述,用b-tree作為索引結構效率是非常高的。
紅黑樹這種結構,h明顯要深的多。由於邏輯上很近的節點(父子)物理上可能很遠,無法利用區域性性,所以紅黑樹的i/o漸進複雜度也為o(h),效率明顯比b-tree差很多。
資料庫 資料庫索引
索引是儲存引擎用於快速找到記錄的一種資料結構。索引以檔案的形式儲存在磁碟中。索引可以包含乙個或多個列的值。儲存引擎查詢資料的時候,先在索引中找對應值,然後根據匹配的索引記錄找到對應的資料行。1.b tree索引 2.雜湊索引 myisam和innodb儲存引擎 只支援btree索引,也就是說預設使用...
資料庫mysql索引 資料庫 mysql索引
mysql 索引 mysql索引的建立對於mysql的高效執行是很重要的,索引可以大大提高mysql的檢索速度。打個比方,如果合理的設計且使用索引的mysql是一輛蘭博基尼的話,那麼沒有設計和使用索引的mysql就是乙個人力三輪車。索引分單列索引和組合索引。單列索引,即乙個索引只包含單個列,乙個表可...
資料庫索引
索引 索引列唯一索引 主鍵索引 聚簇索引和非聚簇索引 如何建立索引 如何刪除索引 使用索引可快速訪問資料庫表中的特定資訊。索引是對資料庫表中一列或多列的值進行排序的一種結構,例如 employee 表的姓 lname 列。如果要按姓查詢特定職員,與必須搜尋表中的所有行相比,索引會幫助您更快地獲得該資...