GitHub 4.8k Star 的Java工程師成神之路 ,不來了解一下嗎?git
GitHub 4.8k Star 的Java工程師成神之路 ,真的不來了解一下嗎?github
GitHub 4.8k Star 的Java工程師成神之路 ,真的肯定不來了解一下嗎?面試
本文來自一位不肯意透露姓名的粉絲投稿sql
相信不少人對於MySQL的索引都不陌生,索引(Index)是幫助MySQL高效獲取數據的數據結構。數據庫
由於索引是MySQL中比較重點的知識,相信不少人都有必定的瞭解,尤爲是在面試中出現的頻率特別高。樓主自認爲本身對MySQL的索引相關知識有不少了解,並且由於最近在找工做面試,因此單獨複習了不少關於索引的知識。markdown
可是,我仍是圖樣圖森破,直到我被阿里的面試官虐過以後我才知道,本身在索引方面的知識,只是個小學生水平。數據結構
如下,是我總結的一次阿里面試中關於索引有關的問題以及知識點。oop
咱們是怎麼聊到索引的呢,是由於我提到咱們的業務量比較大,天天大概有幾百萬的新數據生成,因而有了如下對話:優化
面試官:大家天天這麼大的數據量,都是保存在關係型數據庫中嗎?spa
我:是的,咱們線上使用的是MySQL數據庫
面試官:天天幾百萬數據,一個月就是幾千萬了,那大家有沒有對於查詢作一些優化呢?
我:咱們在數據庫中建立了一些索引(我如今很是後悔我當時說了這句話)。
這裏能夠看到,阿里的面試官並不會像有一些公司同樣拿着題庫一道一道的問,而是會根據面試者作過的事情以及面試過程當中的一些內容進行展開。
面試官:那你能說說什麼是索引嗎?
我:(這道題確定難不住我啊)索引實際上是一種數據結構,可以幫助咱們快速的檢索數據庫中的數據。
面試官:那麼索引具體採用的哪一種數據結構呢?
我:(這道題我也背過)常見的MySQL主要有兩種結構:Hash索引和B+ Tree索引,咱們使用的是InnoDB引擎,默認的是B+樹。
這裏我耍了一個當心機,特地說了一下索引和存儲引擎有關。但願面試官能夠問我一些關於存儲引擎的問題。
面試官:既然你提到InnoDB使用的B+ Tree的索引模型,那麼你知道爲何採用B+ 樹嗎?這和Hash索引比較起來有什麼優缺點嗎?
我:(忽然以爲這道題有點難,可是我仍是憑藉着本身的知識儲備簡單的回答上一些)由於Hash索引底層是哈希表,哈希表是一種以key-value存儲數據的結構,因此多個數據在存儲關係上是徹底沒有任何順序關係的,因此,對於區間查詢是沒法直接經過索引查詢的,就須要全表掃描。因此,哈希索引只適用於等值查詢的場景。而B+ Tree是一種多路平衡查詢樹,因此他的節點是自然有序的(左子節點小於父節點、父節點小於右子節點),因此對於範圍查詢的時候不須要作全表掃描。
面試官:除了上面這個範圍查詢的,你還能說出其餘的一些區別嗎?
我:(這個題我回答的很差,過後百度了一下)
科普時間:B+ Tree索引和Hash索引區別 哈希索引適合等值查詢,可是不沒法進行範圍查詢 哈希索引沒辦法利用索引完成排序 哈希索引不支持多列聯合索引的最左匹配規則 若是有大量重複鍵值得狀況下,哈希索引的效率會很低,由於存在哈希碰撞問題
面試官:剛剛咱們聊到B+ Tree ,那你知道B+ Tree的葉子節點均可以存哪些東西嗎?
我:InnoDB的B+ Tree可能存儲的是整行數據,也有多是主鍵的值。
面試官:那這二者有什麼區別嗎? 我:(當他問我葉子節點的時候,其實我就猜到他可能要問我聚簇索引和非聚簇索引了)在 InnoDB 裏,索引B+ Tree的葉子節點存儲了整行數據的是主鍵索引,也被稱之爲聚簇索引。而索引B+ Tree的葉子節點存儲了主鍵的值的是非主鍵索引,也被稱之爲非聚簇索引。 面試官:那麼,聚簇索引和非聚簇索引,在查詢數據的時候有區別嗎?
我:聚簇索引查詢會更快?
面試官:爲何呢?
我:由於主鍵索引樹的葉子節點直接就是咱們要查詢的整行數據了。而非主鍵索引的葉子節點是主鍵的值,查到主鍵的值之後,還須要再經過主鍵的值再進行一次查詢。
面試官:剛剛你提到主鍵索引查詢只會查一次,而非主鍵索引須要回表查詢屢次。(後來我才知道,原來這個過程叫作回表)是全部狀況都是這樣的嗎?非主鍵索引必定會查詢屢次嗎?
我:(額、這個問題我回答的很差,後來我本身查資料才知道,經過覆蓋索引也能夠只查詢一次)
科普時間——覆蓋索引 覆蓋索引(covering index)指一個查詢語句的執行只用從索引中就可以取得,沒必要從數據表中讀取。也能夠稱之爲實現了索引覆蓋。 當一條查詢語句符合覆蓋索引條件時,MySQL只須要經過索引就能夠返回查詢所須要的數據,這樣避免了查到索引後再返回表操做,減小I/O提升效率。 如,表covering_index_sample中有一個普通索引 idx_key1_key2(key1,key2)。當咱們經過SQL語句:select key2 from covering_index_sample where key1 = 'keytest';的時候,就能夠經過覆蓋索引查詢,無需回表。
面試官:不知道的話不要緊,想問一下,大家在建立索引的時候都會考慮哪些因素呢?
我:咱們通常對於查詢機率比較高,常常做爲where條件的字段設置索引
面試官:那大家有用過聯合索引嗎?
我:用過呀,咱們有對一些表中建立過聯合索引。
面試官:那大家在建立聯合索引的時候,須要作聯合索引多個字段之間順序大家是如何選擇的呢?
我:咱們把識別度最高的字段放到最前面。
面試官:爲何這麼作呢?
我:(這個問題有點把我問蒙了,稍微有些慌亂)這樣的話可能命中率會高一點吧。。。
面試官:那你知道最左前綴匹配嗎?
我:(我忽然想起來原來面試官是想問這個,怪本身剛剛爲何就沒想到這個呢。)哦哦哦。您剛剛問的是這個意思啊,在建立多列索引時,咱們根據業務需求,where子句中使用最頻繁的一列放在最左邊,由於MySQL索引查詢會遵循最左前綴匹配的原則,即最左優先,在檢索數據時從聯合索引的最左邊開始匹配。因此當咱們建立一個聯合索引的時候,如(key1,key2,key3),至關於建立了(key1)、(key1,key2)和(key1,key2,key3)三個索引,這就是最左匹配原則。
雖然我一開始有點懵,沒有聯想到最左前綴匹配,可是面試官仍是引導了我。很友善。
面試官:大家線上用的MySQL是哪一個版本啊呢?
我:咱們MySQL是5.7
面試官:那你知道在MySQL 5.6中,對索引作了哪些優化嗎?
我:很差意思,這個我沒有去了解過。(過後我查了一下,有一個比較重要的 :Index Condition Pushdown Optimization)
科普時間—— Index Condition Pushdown(索引下推) MySQL 5.6引入了索引下推優化,默認開啓,使用SET optimizer_switch = 'index_condition_pushdown=off';能夠將其關閉。官方文檔中給的例子和解釋以下: people表中(zipcode,lastname,firstname)構成一個索引
SELECT * FROM people WHERE zipcode='95054' AND lastname LIKE '%etrunia%' AND address LIKE '%Main Street%';
若是沒有使用索引下推技術,則MySQL會經過zipcode='95054'從存儲引擎中查詢對應的數據,返回到MySQL服務端,而後MySQL服務端基於lastname LIKE '%etrunia%'和address LIKE '%Main Street%'來判斷數據是否符合條件。 若是使用了索引下推技術,則MYSQL首先會返回符合zipcode='95054'的索引,而後根據lastname LIKE '%etrunia%'和address LIKE '%Main Street%'來判斷索引是否符合條件。若是符合條件,則根據該索引來定位對應的數據,若是不符合,則直接reject掉。 有了索引下推優化,能夠在有like條件查詢的狀況下,減小回表次數。
面試官:大家建立的那麼多索引,到底有沒有生效,或者說大家的SQL語句有沒有使用索引查詢大家有統計過嗎?
我:這個尚未統計過,除非遇到慢SQL的時候咱們纔會去排查
面試官:那排查的時候,有什麼手段能夠知道有沒有走索引查詢呢?
我:能夠經過explain查看sql語句的執行計劃,經過執行計劃來分析索引使用狀況
面試官:那什麼狀況下會發生明明建立了索引,可是執行的時候並無經過索引呢?
我:(依稀記得和優化器有關,可是這個問題並無回答好)
科普時間——查詢優化器 一條SQL語句的查詢,能夠有不一樣的執行方案,至於最終選擇哪一種方案,須要經過優化器進行選擇,選擇執行成本最低的方案。 在一條單表查詢語句真正執行以前,MySQL的查詢優化器會找出執行該語句全部可能使用的方案,對比以後找出成本最低的方案。這個成本最低的方案就是所謂的執行計劃。 優化過程大體以下: 一、根據搜索條件,找出全部可能使用的索引 二、計算全表掃描的代價 三、計算使用不一樣索引執行查詢的代價 四、對比各類執行方案的代價,找出成本最低的那一個
面試官:哦,索引有關的知識咱們暫時就問這麼多吧。大家線上數據的事務隔離級別是什麼呀?
我:(後面關於事務隔離級別的問題了,就不展開了)
感受是由於我回答的不夠好,若是這幾個索引問題我都會的話,他還會追問更多,恐怕會被虐的更慘
以上,就是一次面試中關於索引部分知識的問題以及我整理的答案。感受此次面試過程當中關於索引的知識,本身大概可以回答的內容佔70%左右,可是自信徹底答對的內容只佔50%左右,看來本身索引有關的知識瞭解的仍是不夠多。
經過此次面試,發現像阿里這種大廠對於底層知識仍是比較看重的,我之前覺得關於索引最多也就問一下Hash和B+有什麼區別,沒想到最後都能問到查詢優化器上面。
最後,無論本次面試能不能經過,都很是感謝有這樣一次機會,可讓本身看到本身的不足。經過此次面試,我也收穫了不少東西。加油!