mysql資料庫索引 HASH和B樹

2021-09-22 10:11:15 字數 3777 閱讀 4707

什麼是索引?

索引是一種特殊的資料結構,可以用來查詢資料庫表中特定的記錄。他由資料庫中的一列或者多列組成,可以提高資料庫的查詢速度。

我們先看一下如果沒有索引的情況下資料庫是怎麼查詢資料的?

例如查詢

select * from usr where name = '張三';
當執行這句sql語句的的時候,資料庫會逐行遍歷整張表,對於每一行都會比較name是否等於張三,因為是要查詢所有姓名為張三的記錄,所以要遍歷整張表,做了乙個全域性檢索。

使用索引是怎麼查詢的呢?這裡不同的索引儲存型別有不同的查詢方式。

索引的兩種儲存型別 b樹索引和hash索引

不同的資料庫引擎支援不同的索引儲存型別,innodb和myisam支援btree,memory支援hash和btree。

hash儲存

hash儲存是一種雜湊表結構的儲存 

hash儲存的實質是將資料(key/value型別資料)儲存到乙個陣列中,當資料儲存時利用hash函式hash = h(key)得到乙個雜湊值,然後利用雜湊值再去計算出資料應該存放到陣列的某個位置index,將資料存入陣列的index位置,資料查詢時傳入key值,hash = h(key),進而得到index值,直接取出index位置的位址,利用取出的位址去磁碟中直接定位到某一條記錄資料,其時間複雜度為o(1)。

在mysql hash儲存結構的索引中,key值儲存的是列值,也就是新增索引的列的值,value是個指標指向列值對應的行位址。

例如

select * from usr where name = '張三';
通過張三得到hash值進而得到index假如是3,直接利用index=3,到陣列的3位置取出位址0x23109,然後根據位址0x23109去磁碟中取出該位置的資料。 這是種理想的沒發生hash碰撞情況,那如果key值發生碰撞了怎麼辦???????

hash儲存衝突了怎麼辦?

如果是存在多個為張三的資料如果索引採取的是拉鍊法處理這種衝突,查詢的時候解決起來也很輕鬆可以根據拉出來的鍊錶依次讀取位址並到磁碟中讀取資料,如果是其他的解決衝突的方法,例如再hash,開放位址法等,最壞的情況可能是表中只儲存了關鍵字都是相同的key,那麼就避免不了需要檢索整個索引,當記錄數超級多的時候,雖然能提高效率,但是對整個索引表的遍歷工作量也是巨大的。

hash 儲存結構非等值條件查詢怎麼辦?

我們知道hash表這種儲存結構是無序的,可以看出如果是等值查詢的話,hash儲存結構的索引無疑是最快的一種。但是如果進行非等值條件查詢,hash儲存結構的索引將顯得力不從心。例如

select * from user where age < 50 and age >20;
所以hash儲存結構存在缺點

b-樹結構

b-樹的定義

一棵m介的b-樹,或為空樹,或為滿足下列特性的m叉樹

樹中的結點之多有m棵子樹。

若根節點不是葉子結點,則至少有兩顆子樹

除根以外的的所有非終端結點至少有m/2棵子樹

所有的葉結點出現在同一層次上,並且不帶資訊,通常稱為失敗結點。

所有的非終端結點最多有m-1個關鍵字。

b-樹為什麼會出現?

b-樹說了那麼多我個人認為都是以二叉排序樹為基礎的一種改進二叉樹定義就是一棵樹的左子樹小於根節點,根節點小於右子樹,二叉排序樹極端的情況是如果按照順序插入例如 2、5、8、23、67就會出現一條鏈的情況就成了單鏈表,查詢時的平均查詢長度最長,因此出現了平衡二叉樹,平衡二叉樹解決了這種極端的情況,提出了平衡因子(就是左子樹的高度減右子樹的高度),並且平衡因子必須為1、-1、0才能稱之為平衡二叉樹,就是為了減少樹的高度,減小查詢長度。而對於b-樹是為了解決磁碟io速度相對於記憶體來說速度慢出現的,我們都知道對於平衡二叉樹的查詢來說也是分為兩步1.查詢到結點2.將結點讀入記憶體,根據key查詢資料(二叉樹每個結點只有乙個key),平衡二叉樹在查詢時每次磁碟的io查詢,查出乙個結點,結點中只有乙個資料,磁碟的io是非常的慢的,對於此問題就有人想能不能每次很辛苦的磁碟io得到多條資料,這就出現了b-樹這種資料結構,每個結點上存在多個key值,也就是多條資料,這樣就能充分利用每次磁碟的io查詢。

b-樹的查詢兩步1.(磁碟上進行)查詢結點2.(記憶體中進行)將結點讀入記憶體,使用順序查詢或者二分查詢key。

b-樹的查詢過程 例如這棵b-樹

查詢 關鍵字47,首先47>35,查詢a的右子樹,與43,78比較,43<47<78,就順著43右邊臨近的指標向下查詢,47與47,53,64比較發現47=47,即查詢成功。

查詢10 首先根節點比較 10<35,查左子樹,與18比較 10<18查左子樹,10<11,查左子樹,左子樹為失敗結點,查詢結束,查詢失敗。

對於mysql資料庫中的b-樹結構的索引的查詢亦是如此,每個結點上儲存的是乙個關鍵字key和value,也可以說根據關鍵字查詢出 value,而value中儲存的也是磁碟中資料庫的某一條記錄的位址。

可以看出如果是去做等值查詢的話其速度是不及hash儲存的,但是如果是範圍查詢的話那將是非常的快,比如上圖中的是對年齡設定了索引,我們查詢年齡小於35歲的,那麼當第一次與根節點比較時,就能確定左子樹上的所有的都是滿足的,直接去遍歷所有節點即可。

在資料庫中索引的分類

1. 普通索引 建立乙個普通索引時不需要加任何的限制條件 

create index index1 on book(id);
如果是將索引設定在char varchar text欄位上需要指定長度。

例如再varchar型別的name欄位上加索引,查詢時比較前10個位元組,相同就匹配。

create index index1 on book(name(10));
2. 唯一索引 通過unique引數設定的索引為唯一索引

create unique index index1 on book(id);
3. 全文索引

使用fulltext引數設定為全文索引,全文索引只能建立在 char varchar text 型別的字段上。

4. 單列索引  建立在單個欄位上的索引

create index index1 on book(id);
5. 多列索引  建立在多個欄位上的索引

create index index1 on book(id,name(10));
這裡注意:對於多列索引來說,查詢時只有使用了第乙個欄位時才會使用索引查詢,也就是說

select * from book where id = 1;
不會使用索引查詢。

select * from book where id = 1 and name = '張三';
這種情況下才啟動索引。

索引的優點:提高查詢速度

索引的缺點:1.建立索引時 消耗時間。2. 索引需要物理空間。 3. 增刪改操作,需要動態維護索引。 

資料庫mysql索引 資料庫 mysql索引

mysql 索引 mysql索引的建立對於mysql的高效執行是很重要的,索引可以大大提高mysql的檢索速度。打個比方,如果合理的設計且使用索引的mysql是一輛蘭博基尼的話,那麼沒有設計和使用索引的mysql就是乙個人力三輪車。索引分單列索引和組合索引。單列索引,即乙個索引只包含單個列,乙個表可...

MySQL資料庫 索引和事務

1.概念 索引是一種特殊的檔案,包含著對資料表裡所有記錄的引用指標,可以對錶中的一列或多列建立索引,並指定索引的型別,各類索引有各自的資料結構實現 乙個表可以有多個唯一索引 該欄位沒有重複值,但可以有乙個空值 2.作用 資料庫中索引的作用就相當於書籍的目錄,可用於快速定位,檢索資料.索引對於提高資料...

資料庫索引(Oracle和MySql)

索引概念 索引是關聯式資料庫中用於存放每一條記錄的一種物件,主要目的是加快資料的讀取速度和完整性檢查。建立索引是一項技術性要求高的工作。一般在資料庫設計階 段得與資料庫結構一起考慮。應用系統的效能直接與索引的合理直接有關。一.oracle索引 1.索引型別 1 非唯一索引 最常用 uonunique...