我以為我對Mysql索引很瞭解,直到我遇到了阿里的面試官
相信很多人對於MySQL的索引都不陌生,索引(Index)是幫助MySQL高效獲取資料的資料結構。
因為索引是MySQL中比較重點的知識,相信很多人都有一定的瞭解,尤其是在面試中出現的頻率特別高。樓主自認為自己對
MySQL的索引相關知識有很多瞭解,而且因為最近在找工作面試,所以單獨複習了很多關於索引的知識。
但是,我還是圖樣圖森破,直到我被阿里的面試官虐過之後我才知道,自己在索引方面的知識,只是個小學生水平。
以下,是我總結的一次阿里面試中關於索引有關的問題以及知識點。
索引概念、索引模型
我們是怎麼聊到索引的呢,是因為我提到我們的業務量比較大,每天大概有幾百萬的新資料生成,於是有了以下對話:
面試官:你們每天這麼大的資料量,都是儲存在關係型資料庫中嗎?
我:是的,我們線上使用的是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 Stree t%';
如果沒有使用索引下推技術,則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的查詢最佳化器會找出執行該語句所有可能使用的方案,
對比之後找出成本最低的方案。這個成本最低的方案就是所謂的執行計劃。 最佳化過程大致如下: 1、根據搜尋條件,找出所
有可能使用的索引 2、計算全表掃描的代價 3、計算使用不同索引執行查詢的代價 4、對比各種執行方案的代價,找出成本最
低的那一個
面試官:哦,索引有關的知識我們暫時就問這麼多吧。你們線上資料的事務隔離級別是什麼呀?
我:(後面關於事務隔離級別的問題了,就不展開了)
感覺是因為我回答的不夠好,如果這幾個索引問題我都會的話,他還會追問更多,恐怕會被虐的更慘
總結&感悟
以上,就是一次面試中關於索引部分知識的問題以及我整理的答案。感覺這次面試過程中關於索引的知識,自己大概能夠回
答的內容佔70%左右,但是自信完全答對的內容只佔50%左右,看來自己索引有關的知識瞭解的還是不夠多。
透過這次面試,發現像阿里這種大廠對於底層知識還是比較看重的,我以前以為關於索引最多也就問一下Hash和B+有什麼區
別,沒想到最後都能問到查詢最佳化器上面。
最後,不管本次面試能不能透過,都非常感謝有這樣一次機會,可以讓自己看到自己的不足。透過這次面試,我也收穫了很多
東西。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946034/viewspace-2671171/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 我以為我對索引非常瞭解,直到我遇到了阿里面試官...索引阿里面試
- 面試官問我MySQL索引,我面試MySql索引
- 真實的面試翻車經歷,我以為我對Mysql(ACID原理、事務隔離級別、Mysql的鎖機制、事務底層實現原理)事務很熟,直到我遇到了阿里面試官。。。面試MySql阿里
- 【MySQL】我這樣分析MySQL中的事務,面試官對我刮目相看!!MySql面試
- 面試官問我MySQL調優,我真的是面試MySql
- 分散式專題|面試官問我瞭解Mysql主從複製原理麼,我能說不會麼?分散式面試MySql
- 阿里面試官用HashMap把我問倒了阿里面試HashMap
- 面試官:談談你對mysql索引的認識?面試MySql索引
- 阿里面試官:MySQL如何設計索引更高效?阿里面試MySql索引
- 我遇見的那些面試題面試題
- Java高頻面試題:談談你對MySQL索引的瞭解Java面試題MySql索引
- 面試官問我HTTP,我真的是面試HTTP
- 面試官:說說你對NoSQL的瞭解,為什麼要有NoSQL面試SQL
- 對線面試官:Mysql組合索引的生效規則面試MySql索引
- 面試官:說說你對ThreadLocal的瞭解面試thread
- 面試就是你來我往,互相瞭解!面試
- 面試官:我們來聊一聊Redis吧,你瞭解多少就答多少面試Redis
- ## 【分散式事務】面試官問我:MySQL中的XA事務崩潰瞭如何恢復??分散式面試MySql
- 為什麼使用訊息佇列?我這樣回答,面試官直說講得很清楚佇列面試
- 面試官問我Redis叢集,我真的是面試Redis
- 【高併發】面試官問我如何使用Nginx實現限流,我如此回答輕鬆拿到了Offer!面試Nginx
- 當面試官問我JDK Semaphore的原理時,我笑了面試JDK
- 我不是一個合格的面試官面試
- 深入瞭解MySQL的索引MySql索引
- 作為技術面試官,我在面試時考慮什麼?面試
- 面試官:聊一下你對MySQL索引實現原理?面試MySql索引
- 面試官問我JVM調優,我忍不住了!面試JVM
- 剛收到了Facebook的Offer,我是這樣為面試做準備的面試
- 我所瞭解的 CSSCSS
- 面試官:你瞭解Webpack嗎?面試Web
- MYSQL索引為什麼這麼快?瞭解索引的神奇之處MySql索引
- 面試官:談談你對JVM垃圾收集器的瞭解面試JVM
- 【MySQL】面試官問我:MySQL如何實現無資料插入,有資料更新?我是這樣回答的!MySql面試
- 面試官問我會不會Elasticsearch,我語塞了...面試Elasticsearch
- 面試官!讓我們聊聊正則面試
- 如果我是Android面試官二Android面試
- 如果我是Android面試官一Android面試
- 面試官突然問我MySQL儲存過程,我竟然連基礎都不會!(詳細)面試MySql儲存過程