我們常用的索引數(shù)據(jù)結(jié)構(gòu)比較多的是B+TREE。
還有另一種索引數(shù)據(jù)結(jié)構(gòu)是hash,但是innoDB、mysiam數(shù)據(jù)引擎不支持hash數(shù)據(jù)結(jié)構(gòu)。
不同的存儲引擎支持的索引類型也不一樣:
InnoDB 支持事務(wù),支持行級別鎖定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;
MyISAM 不支持事務(wù),支持表級別鎖定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;
Memory 不支持事務(wù),支持表級別鎖定,支持 B-tree、Hash 等索引,不支持 Full-text 索引;
NDB 支持事務(wù),支持行級別鎖定,支持 Hash 索引,不支持 B-tree、Full-text 等索引;
Archive 不支持事務(wù),支持表級別鎖定,不支持 B-tree、Hash、Full-text 等索引;
這個玩意,mysiam和innodb是不支持的,所以,一般情況下用不上了解就好。
一:hash算法復(fù)雜度
哈希算法時間復(fù)雜度為O(1),且不只存在于索引中,每個數(shù)據(jù)庫應(yīng)用中都存在該數(shù)據(jù)結(jié)構(gòu)。
二:HASH索引特性
在MySQL的存儲引擎中,MyISAM不支持哈希索引,而InnoDB中的hash索引是存儲引擎根據(jù)B-Tree索引自建的,后面會對其做具體說明。
hash索引的特點
1、 hash索引是基于hash表實現(xiàn)的,只有查詢條件精確匹配hash索引中的所有列的時候,才能用到hash索引。
2、 對于hash索引中的所有列,存儲引擎都會為每一行計算一個hash碼,hash索引中存儲的就是hash碼。
3、 hash索引包括鍵值、hash碼和指針 。
因為hash索引本身只需要存儲對應(yīng)的hash值,所以索引的結(jié)構(gòu)十分緊湊,這也讓hash索引查找的速度非???。然而,hash索引也是存在其限制的:
三:hash索引的限制
1、 Hash索引必須進行二次查找
使用哈市索引兩次查找,第一次找到相應(yīng)的行,第二次讀取數(shù)據(jù),但是被頻繁訪問到的行一般會緩存在內(nèi)存中,這點對數(shù)據(jù)庫性能的影響不大。
2、hash索引不能用于外排序
hash索引存儲的是hash碼而不是鍵值,所以無法用于外排序
3、hash索引不支持部分索引查找也不支持范圍查找
只能用到等值查詢,不能范圍和模糊查詢
4、hash索引中的hash碼的計算可能存在hash沖突
當出現(xiàn)hash沖突的時候,存儲引擎必須遍歷整個鏈表中的所有行指針,逐行比較,直到找到所有的符合條件的行,若hash沖突很多的話,一些索引的維護代價機會很高,所以說hash索引不適用于選擇性很差的列上(重復(fù)值很多)。姓名、性別、身份證(合適)
上面說到InnoDB的“自適應(yīng)hash索引”。就是當InnoDB注意到某些索引值被使用的非常頻繁時,它會在內(nèi)存中基于B-Tree索引上在創(chuàng)建一個hash索引,這樣就讓B-tree索引也具有hash索引的一些優(yōu)點。這是一個完全自動的內(nèi)部的行為,用戶無法控制或配置,不過,如果有需要,完全可以關(guān)閉該功能。
四:創(chuàng)建自定義hash索引
若存儲引擎不支持hash索引,又想擁有hash索引所帶來的性能提升,則可以模擬InnoDB一樣創(chuàng)建哈希索引。
思路也比較簡單,就是在B-tree基礎(chǔ)上創(chuàng)建一個偽哈希索引。這和真正的hash索引不是一回事,因為還是采用B-Tree進行查找,但是它使用的是hash值而不是鍵本身進行查找。只需要在查詢的where子句中手動指定使用hash函數(shù)即可。下面舉個簡單的例子:
比如:當我們需要存儲大量的URL,并需要根據(jù)URL進行搜索查找。若用B-Tree來存儲URL,存儲的內(nèi)容就會很大。此時的查詢語句就是:
select id from url where url = "www.baidu.com";
若刪除原來的url列上的索引,而新增一個被索引的url_crc列,使用crc32做hash函數(shù),則可以使用如下方式查詢:
select id from url where url = "www.baidu.com" and url_crc=CRC32("www.baidu.com");
這樣做的話,性能就會有很大提升,因為mysql優(yōu)化器會使用這個選擇性高而體積很小的基于url_crc列的多音來完成查找。即使有多個記錄相同的索引值,查找仍然很快,只需要根據(jù)hash值做快速的整數(shù)比較就能找到索引條目,然后一一返回對應(yīng)的行。
五:Hash缺點
1、需要維護hash值,可以手動維護,也可以使用觸發(fā)器實現(xiàn)。
2、若數(shù)據(jù)表非常大的話,CRC32()會出現(xiàn)大量hash沖突,則可以自己實現(xiàn)一個64位的hash函數(shù),這個自定義的hash函數(shù)要返回整數(shù)而不是字符串,因為范圍整數(shù),對此效率更高。一個簡單的辦法就是使用MD5()函數(shù)返回值的一部分來作為自定義的hash函數(shù)。但是這可能比自己寫一個hash算法性能要差一些。
以上大概就是hash索引的基本內(nèi)容。
再說一次,這個玩意他不支持mysiam和innodb,所以,可能是用的不多。
有好的建議,請在下方輸入你的評論。
歡迎訪問個人博客
https://guanchao.site