mysql索引面試

2021-10-07 08:56:21 字數 4635 閱讀 9600

1

索引概念、索引模型

我們是怎麼聊到索引的呢,是因為我提到我們的業務量比較大,每天大概有幾百萬的新資料生成,於是有了以下對話:

**q:**你們每天這麼大的資料量,都是儲存在關係型資料庫中嗎?

**a:**是的,我們線上使用的是mysql資料庫

**q:**每天幾百萬資料,乙個月就是幾千萬了,那你們有沒有對於查詢做一些優化呢?

**a:**我們在資料庫中建立了一些索引(我現在非常後悔我當時說了這句話)

**q:**那你能說說什麼是索引嗎?

a:(這道題肯定難不住我啊)索引其實是一種資料結構,能夠幫助我們快速的檢索資料庫中的資料

**q:**那麼索引具體採用的哪種資料結構呢?

a:(這道題我也背過)常見的mysql主要有兩種結構:hash索引和b+ tree索引,我們使用的是innodb引擎,預設的是b+樹

**q:**既然你提到innodb使用的b+ 樹的索引模型,那麼你知道為什麼採用b+ 樹嗎?這和hash索引比較起來有什麼優缺點嗎?

**a:**因為hash索引底層是雜湊表,雜湊表是一種以key-value儲存資料的結構,所以多個資料在儲存關係上是完全沒有任何順序關係的,所以,對於區間查詢是無法直接通過索引查詢的,就需要全表掃瞄。**所以,雜湊索引只適用於等值查詢的場景。**而b+ 樹是一種多路平衡查詢樹,所以他的節點是天然有序的(左子節點小於父節點、父節點小於右子節點),所以對於範圍查詢的時候不需要做全表掃瞄

**q:**除了上面這個範圍查詢的,你還能說出其他的一些區別嗎?

b+ tree索引和hash索引區別?

雜湊索引適合等值查詢,但是無法進行範圍查詢

雜湊索引沒辦法利用索引完成排序

雜湊索引不支援多列聯合索引的最左匹配規則

如果有大量重複鍵值的情況下,雜湊索引的效率會很低,因為存在雜湊碰撞問題

2

聚簇索引、覆蓋索引

**q:**剛剛我們聊到b+ tree ,那你知道b+ tree的葉子節點都可以存哪些東西嗎?

**a:**innodb的b+ tree可能儲存的是整行資料,也有可能是主鍵的值

**q:**那這兩者有什麼區別嗎?

a:(當他問我葉子節點的時候,其實我就猜到他可能要問我聚簇索引和非聚簇索引了)在 innodb 裡,索引b+ tree的葉子節點儲存了整行資料的是主鍵索引,也被稱之為聚簇索引。而索引b+ tree的葉子節點儲存了主鍵的值的是非主鍵索引,也被稱之為非聚簇索引

**q:**那麼,聚簇索引和非聚簇索引,在查詢資料的時候有區別嗎?

**a:**聚簇索引查詢會更快?

**q:**為什麼呢?

**a:**因為主鍵索引樹的葉子節點直接就是我們要查詢的整行資料了。而非主鍵索引的葉子節點是主鍵的值,查到主鍵的值以後,還需要再通過主鍵的值再進行一次查詢

**q:**剛剛你提到主鍵索引查詢只會查一次,而非主鍵索引需要回表查詢多次。(後來我才知道,原來這個過程叫做回表)是所有情況都是這樣的嗎?非主鍵索引一定會查詢多次嗎?

a:(額、這個問題我回答的不好,後來我自己查資料才知道,通過覆蓋索引也可以只查詢一次)

覆蓋索引?

覆蓋索引(covering index)指乙個查詢語句的執行只用從索引中就能夠取得,不必從資料表中讀取。也可以稱之為實現了索引覆蓋。

當一條查詢語句符合覆蓋索引條件時,mysql只需要通過索引就可以返回查詢所需要的資料,這樣避免了查到索引後再返回表操作,減少i/o提高效率。

如,表covering_index_sample中有乙個普通索引 idx_key1_key2(key1,key2)。

當我們通過sql語句:select key2 from covering_index_sample where key1 = 『keytest』;的時候,就可以通過覆蓋索引查詢,無需回表。

3

聯合索引、最左字首匹配

**q:**不知道的話沒關係,想問一下,你們在建立索引的時候都會考慮哪些因素呢?

**a:**我們一般對於查詢概率比較高,經常作為where條件的字段設定索引

q:那你們有用過聯合索引嗎?

**a:**用過呀,我們有對一些表中建立過聯合索引

**q:**那你們在建立聯合索引的時候,需要做聯合索引多個字段之間順序你們是如何選擇的呢?

**a:**我們把識別度最高的字段放到最前面

**q:**為什麼這麼做呢?

a:(這個問題有點把我問蒙了,稍微有些慌亂)這樣的話可能命中率會高一點吧。。。

q:那你知道最左字首匹配嗎?

a:(我突然想起來原來面試官是想問這個,怪自己剛剛為什麼就沒想到這個呢。)哦哦哦。您剛剛問的是這個意思啊,在建立多列索引時,我們根據業務需求,where子句中使用最頻繁的一列放在最左邊,因為mysql索引查詢會遵循最左字首匹配的原則,即最左優先,在檢索資料時從聯合索引的最左邊開始匹配。所以當我們建立乙個聯合索引的時候,如(key1,key2,key3),相當於建立了(key1)、(key1,key2)和(key1,key2,key3)三個索引,這就是最左匹配原則

4

索引下推、查詢優化

**q:**你們線上用的mysql是哪個版本啊呢?

**a:**我們mysql是5.7

**q:**那你知道在mysql 5.6中,對索引做了哪些優化嗎?

**a:**不好意思,這個我沒有去了解過。(事後我查了一下,有乙個比較重要的 :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條件查詢的情況下,減少回表次數。

**q:**你們建立的那麼多索引,到底有沒有生效,或者說你們的sql語句有沒有使用索引查詢你們有統計過嗎?

**a:**這個還沒有統計過,除非遇到慢sql的時候我們才會去排查

**q:**那排查的時候,有什麼手段可以知道有沒有走索引查詢呢?

**a:**可以通過explain檢視sql語句的執行計畫,通過執行計畫來分析索引使用情況

**q:**那什麼情況下會發生明明建立了索引,但是執行的時候並沒有通過索引呢?

a:(大概記得和優化器有關,但是這個問題並沒有回答好)

查詢優化器?

一條sql語句的查詢,可以有不同的執行方案,至於最終選擇哪種方案,需要通過優化器進行選擇,選擇執行成本最低的方案。

在一條單錶查詢語句真正執行之前,mysql的查詢優化器會找出執行該語句所有可能使用的方案,對比之後找出成本最低的方案。

這個成本最低的方案就是所謂的執行計畫。優化過程大致如下:

1、根據搜尋條件,找出所有可能使用的索引

2、計算全表掃瞄的代價

3、計算使用不同索引執行查詢的代價

4、對比各種執行方案的代價,找出成本最低的那乙個

**q:**哦,索引有關的知識我們暫時就問這麼多吧。你們線上資料的事務隔離級別是什麼呀?

a:(後面關於事務隔離級別的問題了,就不展開了)

MYSQL面試 索引(四)

7.索引 資料2 索引sql語法 資料3 索引 explain分析 資料4 聚集索引和非聚集索引及優化 資料5 using filesore優化索引案例 索引的使用場景 對於非常 小 的表 大部分情況下簡單的全表掃瞄比建立索引更高效 不適用索引 對於 中到大型 的表,索引就非常有效 適用索引 但是對...

面試整理 mysql索引

mysql索引分成以下幾類 b 索引 hash索引 全文索引 b 樹索引分為聚集索引和非聚集索引 輔助索引 聚集索引是通過表的主鍵來構建b 樹,聚集索引不僅包括索引的值還包括其他列的相關資訊。聚集索引中的記錄是根據鍵值順序存放的。聚集索引的非葉子節點儲存的是 健值,索引 對。位址為指向下一層的指標,...

Mysql面試總結 索引

1.資料庫中最常見的慢查詢優化方式是什麼 2.為什麼加索引能優化慢查詢 3.哪些資料結構能夠提高查詢速度 4.為什麼這些資料結構能優化查詢速度 mysql還要選擇b 樹 索引是幫助mysql高效獲取資料的資料結構 索引儲存在檔案系統中 索引的檔案儲存形式與儲存引擎相關 索引的結構 hash 二叉樹b...