更新時間:2022-12-30 15:09:18 來源:動力節(jié)點 瀏覽1356次
很多同學(xué)面對Mysql索引相關(guān)的面試題都是死記硬背的,這肯定是不行的,也不容易記住,所以大家還是要循循漸進(jìn),從理解開始,慢慢掌握,當(dāng)然對于想要準(zhǔn)備面試題的同學(xué),這幾個問題是需要記住并理解的:
當(dāng)在非常大的表中進(jìn)行查詢,如果數(shù)據(jù)庫進(jìn)行全表遍歷的話那么速度是會非常慢的,而我們的索引則可以建立一個b+樹的結(jié)構(gòu),可以自上而下的去進(jìn)行查詢(有點像二分查找),可以在一定程度避免走全表查詢,這樣查詢的速度是非??斓?
①一般情況下掃描索引的速度是遠(yuǎn)遠(yuǎn)大于掃描全表的速度的;
②索引是天然有序的,具備B+樹的快速檢索(類似二分查找)
③索引天然聚合(存儲的數(shù)據(jù)是去重了的),在一些操作(分組,排序等)中不會再產(chǎn)生中間表;
對于查詢占主要的應(yīng)用來說,索引顯得尤為重要。很多時候性能問題很簡單的就是因為我們忘了添加索引而造成的,或者說沒有添加更為有效的索引導(dǎo)致。如果不加索引的話,那么查找任何哪怕只是一條特定的數(shù)據(jù)都會進(jìn)行一次全表掃描,如果一張表的數(shù)據(jù)量很大而符合條件的結(jié)果又很少,那么不加索引會引起致命的性能下降。但是也不是什么情況都非得建索引不可,比如性別可能就只有兩個值,建索引不僅沒什么優(yōu)勢,還會影響到更新速度,這被稱為過度索引。
1. 頻繁作為where條件語句查詢的字段
這是因為在頻繁查詢的字段列創(chuàng)建索引可以避免查詢數(shù)據(jù)的時候走全表掃描,這樣查詢的速度就會大大增加;
2. 關(guān)聯(lián)字段需要建立索引
關(guān)聯(lián)的字段一般都是通過主鍵來進(jìn)行兩張表的關(guān)聯(lián),主鍵大部分情況下都是主鍵;如果關(guān)聯(lián)的兩個主鍵都沒有索引,那么我們一般優(yōu)先考慮在被驅(qū)動表中的字段建立索引,因為在外連接的查詢中被驅(qū)動表是需要被多次重復(fù)掃描的,那么讓它走索引查詢是會快很多的,可以避免更多次數(shù)的全表掃描;
3. 排序字段可以建立索引
這是因為b+樹結(jié)構(gòu)的索引是天然有序的!
4.分組字段可以建立索引,因為分組的前提是排序
5.統(tǒng)計字段可以建立索引,例如count(),max()
這是因為索引是天然聚合的,就是存放在b+樹的數(shù)據(jù)是已經(jīng)去重的數(shù)據(jù)了,存儲的數(shù)據(jù)還是比較緊湊的,那么通過B+樹的雙向指針可以更快的找到要統(tǒng)計的數(shù)據(jù),而且在加了索引的列的統(tǒng)計的時候MySQL是不會產(chǎn)生中間表來專門去重了,可以減少不必要的性能開銷;(在沒有索引的列的統(tǒng)計,分組 的SQL語句中,MySQL都是會創(chuàng)建臨時表來存儲數(shù)據(jù)的)
1.頻繁更新的字段不適合建立索引 (因為數(shù)據(jù)比較大的表的索引的創(chuàng)建是非常耗時的,而且如果一個字段被頻繁更新那么我們還需要頻繁的維護(hù)這個樹的結(jié)構(gòu),這個開銷是非常大的)
2.參與列計算的列不適合建索引,因為計算后的列的值最后不一定是有序的,不有序那么就會導(dǎo)致索引會失效
3.表數(shù)據(jù)可以確定比較少的不需要建索引
4.數(shù)據(jù)重復(fù)且分布比較均勻的的字段不適合建索引,因為說不定你對這種索引字段的查詢的速度還沒有全表掃描快,例如性別,真假值;
5.where條件中用不到的字段不適合建立索引,因為索引是可以幫助我們在查詢的時候大大的提高查詢效率,但是在增加,刪除操作確實異常消耗性能的,因為需要不斷的維護(hù)B+樹的結(jié)構(gòu)(有序你就需要維護(hù)),你查詢的時候都不需要使用到這個字段了,那還建立這個字段的索引列干啥?等著吃你系統(tǒng)的性能嘛?
①因為b+樹是把數(shù)據(jù)都存放在葉子節(jié)點中的(在innodb存儲引擎中一個b+樹的節(jié)點是 一頁(16k)),那么在固定大小的容量中 B+樹的非葉子節(jié)點中就可以存放更多的索引列數(shù)據(jù),也就意味著B+樹的非葉子節(jié)點存儲的數(shù)據(jù)的范圍就會更大,那么樹的層次就會更少,IO次數(shù)也就會更少;
②b+樹的葉子節(jié)點維護(hù)了一個雙向鏈表,它更有利于范圍查詢
③b+樹中的葉子節(jié)點和非葉子節(jié)點的數(shù)據(jù)都是分開存儲的,分別存放在葉子節(jié)點段和非葉子節(jié)點段,那么進(jìn)行全表掃描的時候,就可以不用再掃描非葉子節(jié)點的數(shù)據(jù)了,并且這是一個順序讀取數(shù)據(jù)的過程(順序讀比隨機(jī)讀的速度要快很多很多),掃描的速度也會大大提高;
以上就是“大廠考核重點:mysql索引面試題”,你能回答上來嗎?如果想要了解更多的Java面試題相關(guān)內(nèi)容,可以關(guān)注動力節(jié)點Java官網(wǎng)。
相關(guān)閱讀