mysql索引实现原理
閱讀目錄
- Myisam引擎(非聚集索引)
- ?Innodb引擎(聚集索引)
什么是索引:
索引是一種高效獲取數(shù)據(jù)的存儲(chǔ)結(jié)構(gòu),例:hash、 二叉、 紅黑。
Mysql為什么不用上面三種數(shù)據(jù)結(jié)構(gòu)而采用B+Tree:
若僅僅是 ?select * from table where id=45 ?, 上面三種算法可以輕易實(shí)現(xiàn),但若是select * from table where id<6 ?, 就不好使了,它們的查找方式就類似于"全表掃描",因?yàn)樗麄兊母叨仁遣豢煽氐?如下圖)。B+Tree的高度是可控的,mysql通常是3到5層。注意:B+Tree只在最末端葉子節(jié)點(diǎn)存數(shù)據(jù),葉子節(jié)點(diǎn)是以鏈表的形勢(shì)互相指向的。
回到頂部
Myisam引擎(非聚集索引)
若以這個(gè)引擎創(chuàng)建數(shù)據(jù)庫(kù)表Create table user (…..),它實(shí)際是生成三個(gè)文件:
user.myi ??索引文件 ????user.myd數(shù)據(jù)文件 ????user.frm數(shù)據(jù)結(jié)構(gòu)類型。
? 如下圖:當(dāng)我們執(zhí)行 ?select?* from user where id = 1的時(shí)候,它的執(zhí)行流程。
(1)查看該表的myi文件有沒(méi)有以id為索引的索引樹(shù)。
(2)根據(jù)這個(gè)id索引找到葉子節(jié)點(diǎn)的id值,從而得到它里面的數(shù)據(jù)地址。(葉子節(jié)點(diǎn)存的是索引和數(shù)據(jù)地址)。
(3)根據(jù)數(shù)據(jù)地址去myd文件里面找到對(duì)應(yīng)的數(shù)據(jù)返回出來(lái)。
?
?Innodb引擎(聚集索引)
若以這個(gè)引擎創(chuàng)建數(shù)據(jù)庫(kù)表Create table user (…..),它實(shí)際是生成兩個(gè)文件:
user.ibd ??索引文件 ???????user.frm數(shù)據(jù)結(jié)構(gòu)類型
因?yàn)閕nnodb引擎創(chuàng)建表默認(rèn)就是以主鍵為索引,所以不需要myi文件。
下圖為innodb表的結(jié)構(gòu)圖:很顯然它與myisam最大的區(qū)別是將整條數(shù)據(jù)存在葉子節(jié)點(diǎn),而不是地址。(葉子節(jié)點(diǎn)存的是主鍵索引和數(shù)據(jù)信息)
若此時(shí),你在其他列創(chuàng)建索引例如name,它就會(huì)另外創(chuàng)建一個(gè)以name為索引的索引樹(shù),(葉子節(jié)點(diǎn)存的是索引和主鍵索引)。
你在執(zhí)行select * from user where name = ‘吳磊’,他的執(zhí)行過(guò)程如下:
(1)找到name索引樹(shù)
(2)根據(jù)name的值找到該樹(shù)下葉子的name索引和主鍵值
(3)用主鍵值去主鍵索引樹(shù)去葉子節(jié)點(diǎn)到該條數(shù)據(jù)信息
MyISAM引擎和InnoDB引擎的區(qū)別
MyISAM:支持全文索引;不支持事務(wù);它是表級(jí)鎖;會(huì)保存表的具體行數(shù).
InnoDB:5.6以后才有全文索引;支持事務(wù);它是行級(jí)鎖;不會(huì)保存表的具體行數(shù).
一般:不用事務(wù)的時(shí)候,count計(jì)算多的時(shí)候適合myisam引擎。對(duì)可靠性要求高就是用innodby引擎。推薦用InnoDB引擎.
加了索引之后能夠大幅度的提高查詢速度,但是索引也不是越多越好,一方面它會(huì)占用存儲(chǔ)空間,另一方面它會(huì)使得寫(xiě)操作變得很慢。通常我們對(duì)查詢次數(shù)比較頻繁,值比較多的列才建索引。
例如:select * from user where sex = "女", 這個(gè)就不需要建立索引,因?yàn)樾詣e一共就兩個(gè)值,查詢本身就是比較快的。
select * from user where user_id = 1995 ,這個(gè)就需要建立索引,因?yàn)閡ser_id的值是非常多的。
B+Tree的特性
(1)由圖能看出,單節(jié)點(diǎn)能存儲(chǔ)更多數(shù)據(jù),使得磁盤(pán)IO次數(shù)更少。
(2)葉子節(jié)點(diǎn)形成有序鏈表,便于執(zhí)行范圍操作。
(3)聚集索引中,葉子節(jié)點(diǎn)的data直接包含數(shù)據(jù);非聚集索引中,葉子節(jié)點(diǎn)存儲(chǔ)數(shù)據(jù)地址的指針。
?
總結(jié)
以上是生活随笔為你收集整理的mysql索引实现原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 经典算法题 -- 判断单链表是否成环及寻
- 下一篇: Redis 是属于多线程还是单线程?