你都理解MySQL索引的這些高頻面試題嗎?
前言
作為 Java 開發(fā)人員或者后端開發(fā)人員,面試中永遠避不了數(shù)據(jù)庫中索引,這些問題有時候真的非常頭疼,特別是面試官不僅僅會考察基礎知識,還會結合簡歷上的項目經(jīng)驗,所以我們非常有必要徹底吃透索引。當然啦,作為關系型數(shù)據(jù)庫的代表,MySQL 一直在不斷發(fā)展壯大中,MySQL 索引也成為了大規(guī)模高并發(fā)業(yè)務場景的利器。今天收集了一些經(jīng)典且高頻的MySQL 索引面試題,希望能夠幫助到小伙伴們~
1. MySQL 支持哪些存儲引擎?
【參考答案】
MySQL 支持的存儲引擎主要有四種:
(1)InnoDB 支持事務,行級鎖定和外鍵,是事務型數(shù)據(jù)庫的首選引擎;MySQL5.5.5 之后的默認存儲引擎;
(2)MyISAM 擁有較高的插入、查詢速度,但不支持事務。MySQL5.5.5 之前的默認存儲引擎;
(3)Memory 基于散列,存儲在內(nèi)存中,對臨時表有用。常見的應用場景是:臨時存放數(shù)據(jù),數(shù)據(jù)量不大,并且不需要較高的數(shù)據(jù)安全性;
(4)Archive 支持高并發(fā)的插入操作,但是本身不是事務安全的。常見的應用場景:存儲歸檔數(shù)據(jù),如記錄日志信息可以使用 Archive。
2. InnoDB 和 MyISAM 有什么區(qū)別呢?
【參考答案】
InnoDB 支持事務;而 MyISAM 不支持事物,強調(diào)的是性能,查詢速度更快; InnoDB 支持行級鎖和表級鎖(默認行級鎖),而 MyISAM 只支持表級鎖; InnoDB 支持 MVCC, 而 MyISAM 不支持 MVCC; InnoDB 支持外鍵,而 MyISAM 不支持外鍵; InnoDB早期版本不支持全文索引(從 MySQL5.6 開始支持全文索引),而 MyISAM 支持; InnoDB 不保存表的具體行數(shù),count () 時要掃描一遍整個表來計算有多少行;MyISAM 則內(nèi)置了一個計數(shù)器,count () 時它直接從計數(shù)器中讀。
注意:在 MySQL 中,索引就是在存儲引擎層實現(xiàn)的,不同存儲引擎的索引的工作方式并不一樣,即使不同的存儲引擎支持同一種類型的索引,其底層的實現(xiàn)也可能不同。而這些存儲引擎中以 InnoDB 應用最廣泛,很多面試題也圍繞著它展開。
3. MySQL 索引底層是什么結構?選擇采用此結構有什么好處?
【參考答案】
MySQL 索引底層采用 B + 樹的存儲結構。采用 B + 樹的原因:
(1)索引文件很大,不能全部存儲在內(nèi)存中,只能存儲到磁盤上,因此索引的數(shù)據(jù)結構要盡量減少查找過程中磁盤 I/O 的存取次數(shù);
(2)數(shù)據(jù)庫系統(tǒng)利用了磁盤預讀原理和磁盤預讀,將一個節(jié)點的大小設為等于一個頁,這樣每個節(jié)點只需要一次 I/O 就可以完全載入。而 B + 樹的高度是 2~4,檢索一次最多只需要訪問 4 個節(jié)點(4 次,即樹的高度)。
4. 為什么不選擇 B 樹?
【參考答案】
B + 樹所有的 Data 域在葉子節(jié)點,其余節(jié)點用來索引,而 B 樹是每個索引節(jié)點都會有 Data 域;并且 B + 樹所有葉子節(jié)點之間都有一個鏈指針。這樣遍歷葉子節(jié)點就能獲得全部數(shù)據(jù),從而支持區(qū)分查詢。在數(shù)據(jù)庫中基于范圍的查詢是非常頻繁的,而 B 樹不支持這樣的遍歷操作。
5. 為什么不選擇哈希表?
【參考答案】
哈希表只適用與查找等值查詢, 不能支持區(qū)分條件(大于小于查詢)、模糊查詢等; hash 索引雖然在等值查詢上較快,但是不穩(wěn)定,性能不可預測,當某個鍵值存在大量重復的時候,發(fā)生 hash 碰撞,此時效率可能極差。而 B + 樹的查詢效率比較穩(wěn)定。
6. 為什么不選擇紅黑樹?
【參考答案】
紅黑樹往往高度過大,從頁造成磁盤 IO 讀寫過于頻繁,效率低下。而且邏輯上很近的節(jié)點(父子)物理上可能很遠,無法利用局部性原理。
7. MySQL 支持的索引類型是哪些?
【參考答案】
普通索引:用表中的普通列構建的索引,沒有任何限制; 唯一索引:唯一索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一; 主鍵索引:是一種特殊的唯一索引,根據(jù)主鍵建立索引,不允許重復,不允許空值; 全文索引:通過過建立倒排索引,快速匹配文檔的方式。MySQL 5.7.6 之前僅支持英文,MySQL 5.7.6 之后支持中文; 組合索引:又叫聯(lián)合索引。用多個列組合構建的索引,這多個列中的值不允許有空值??梢栽趧?chuàng)建表的時候指定,也可以修改表結構。
8. 知道聚集索引和非聚集索引嗎?
【參考答案】
聚集索引 (clustered index),又稱為主索引,該索引中鍵值的邏輯順序決定了表中相應行的物理順序。因為數(shù)據(jù)真正的數(shù)據(jù)只能有一種排序方式,所以一個表上只能有一個聚簇索引。 非聚集索引 (secondary index),又稱為輔助索引、普通索引,該索引的邏輯順序與磁盤上行的物理存儲順序不同,一個表可以包含多個非聚集索引。
注意:聚集索引 / 非聚集索引不是一種索引類型,而是一種存儲數(shù)據(jù)的方式。在 InnoDB 中它們還有一個非常重要的區(qū)別:聚集索引的葉子節(jié)點的的 data 域包含了完整的數(shù)據(jù)記錄,而非聚集索引的葉子節(jié)點的 data 域記錄著主鍵的值,因此在使用非聚集索引進行查找時,需要先查找到主鍵值,然后再到聚集索引中進行查找,這稱之為回表查詢。
9. 索引什么時候會失效?
【參考答案】
索引失效通常有以下原因:
條件中有 or; like 查詢(以 % 開頭); 如果列類型是字符串,那一定要在條件中將數(shù)據(jù)使用引號引用起來,否則不使用索引; 對列進行函數(shù)運算(如 where md5 (password) = “xxxx”); 負向查詢條件會導致無法使用索引,比如 NOT IN,NOT LIKE,!= 等; 對于聯(lián)合索引,不是使用的第一部分 (第一個),則不會使用索引(最左匹配); 如果 mysql 評估使用全表掃描要比使用索引快,則不使用索引;。
追問:表 A 建立了 INDEX (col1,col2,col3) 的聯(lián)合索引,where 條件中使用 col1 = a1 and col3=c1 索引是否有效?
答案:索引有效。
10. 索引有什么缺點?
【參考答案】
索引需要額外的占用物理空間,索引越多,所以空間越多; 當對表中的數(shù)據(jù)進行增加、刪除和修改的時候,索引也要動態(tài)的維護,降低了數(shù)據(jù)的寫入速度;
總結
MySQL 索引既是 MySQL 面試中的高頻題,也是項目中可以提高生產(chǎn)力的有力工具,實踐性非常強,因此強烈建議大家在項目多多實踐,才能靈活運用索引,實踐出真知嘛
