InnoDB 和 MyISAM 的區(qū)別
事務方面
InnoDB支持事務,MyISAM不支持事務。這是Mysql將默認存儲引擎從MyISAM變成InnoDB的重要原因之一
外鍵方面
InnoDB支持外鍵,而MyISAM不支持。對一個包含外鍵的InnoDB表轉(zhuǎn)為MyISAM會失敗
索引層面
InnoDB是聚集(聚簇)索引,MyISAM是非聚集(非聚簇)索引。
MyISAM 支持 FULLTEXT 類型的全文索引。
InnoDB不支持FULLTEXT類型的全文索引,但是InnoDB可以使用sphinx插件支持全文索引,并且效果更好。
鎖粒度方面
InnoDB最小的鎖粒度是行鎖,MyISAM最小的鎖粒度是表鎖。
一個更新語句會鎖住整張表,導致其他查詢和更新都會被阻塞,因此并發(fā)訪問受限。
這也是Mysql將默認存儲引擎從MyISAM變成InnoDB的重要原因之一
硬盤存儲結(jié)構(gòu)
MyISAM在硬盤上存儲成三個文件。第一個文件的名字以表的名字開始,擴展名指出文件類型。
- .frm 文件存儲 表的定義
- 數(shù)據(jù)文件 的擴展名為 .MYD(MYData)
- 索引文件 的擴展名為 .MYI (MYIndex)
InnoDB存儲引擎存儲數(shù)據(jù)庫數(shù)據(jù),一共有兩個文件(沒有專門保存數(shù)據(jù)的文件)
- Frm文件:表的定義文件
- Ibd文件:數(shù)據(jù)和索引存儲文件。數(shù)據(jù)以主鍵進行聚集存儲,把真正的數(shù)據(jù)保存在葉子節(jié)點中
聚簇索引 和 非聚簇索引
聚簇索引(InnoDB)
將數(shù)據(jù)存儲和索引放到了一塊,索引結(jié)構(gòu)的葉子節(jié)點保存了行數(shù)據(jù)
表數(shù)據(jù)按照索引的順序來存儲的,也就是說索引項的順序與表中記錄的物理順序一致
InnoDB中,在聚簇索引之上創(chuàng)建的索引稱之為輔助索引,像組合索引、前綴索引、唯一索引等等
左側(cè) 聚簇索引中 B+樹的葉子節(jié)點中直接存儲了數(shù)據(jù)
右側(cè) 輔助索引(又稱二級索引),右側(cè)的將user_name設(shè)置為普通索引,葉子節(jié)點存儲數(shù)據(jù)記錄主鍵的key,在通過key去聚簇索引中查詢得到葉子節(jié)點存儲的數(shù)據(jù)記錄
PS:為什么不推薦使用select * ?
如果只查id,通過一次查詢即可查出數(shù)據(jù),如果使用select * 包含了其他字段,查詢次數(shù)不止一次導致效率較低
非聚簇索引(MyISAM)
將數(shù)據(jù)與索引分開存儲,表數(shù)據(jù)存儲順序與索引順序無關(guān)
1、 葉子節(jié)點保存的是數(shù)據(jù)的地址,根據(jù)ID在B+樹中找到存儲該行數(shù)據(jù)的物理地址
2、根據(jù)該物理地址在數(shù)據(jù)文件中拿到數(shù)據(jù)
索引失效底層原理
索引為什么會失效:
1、使用最佳左前綴法則:
首先,聯(lián)合索引,最左側(cè)的數(shù)據(jù)是有序的,也就是a是有序的,在最滿足最左前綴法時,右側(cè)的數(shù)據(jù)是有序的,當a固定時,b是有序的。
如最下方的圖,當我們使用最左邊的字段時,假如where a?= 1 and b = 1?,此時,a = 1固定了,b也是有序的,所以使用到了索引。
此時當我們使用 where b = 1 不符合最左前綴法則,在a沒有固定的情況下,b是無序的,此時如何在一個無序的B+樹上找到你所需要的值?沒有走到索引,導致進行了全表查詢
2、大于號右邊的索引會失效:
比如 where a > 1 and b = 1? 根據(jù)a >1 的數(shù)據(jù) 如下圖,此時去找b = 1的數(shù)據(jù),此時b是無序的,所以無法通過二分查找去查找b的數(shù)據(jù),沒有使用到索引
此時如果 是 a = 1 則滿足索引
3、like索引會失效:
在數(shù)據(jù)庫中,string類型的也會根據(jù)26個字母來進行排序,此時如果使用 user_name like?'a%'?
此時就滿足索引,如果使用user_name like?'%a' 或者 user_name like?'%a%',同理a右邊的字母是無序的,無法使用索引
文章來源:http://www.zghlxwxcb.cn/news/detail-438585.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-438585.html
以下用法會導致索引失效:
- 計算,如:+、-、*、/、!=、<>、is null 、 is not null 、 or
- 函數(shù) 如:sum() round() 等
- 手動/自動類型轉(zhuǎn)換 如 id ="1",本來是數(shù)字,寫成了字符串
到了這里,關(guān)于Mysql-InnoDB索引:普通索引、主鍵索引、唯一索引、組合索引的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!