溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

MySQL索引原理是什么

發(fā)布時(shí)間:2020-09-29 17:35:09 來源:億速云 閱讀:184 作者:小新 欄目:MySQL數(shù)據(jù)庫

這篇文章主要介紹MySQL索引原理是什么,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

摘要: 就一起來聊一聊MySQL索引。 什么是索引? 百度百科是這樣描述的: 索引是為來加速對(duì)表中數(shù)據(jù)行中的檢索而創(chuàng)建的一種分散的數(shù)據(jù)結(jié)果,時(shí)針對(duì)表而建立的,它是由數(shù)據(jù)頁面以外的索引頁面組成,每個(gè)索引頁中的行都含有邏輯指針,以便加速檢索物理數(shù)據(jù) 其實(shí),索引的概念大家都很清楚,也知道索引能夠提升查詢效率,但大部分童鞋在怎么建索引,建在哪些字段上有以下常見誤解: 新建表時(shí)不需要建索引,后續(xù)才添加索引 where條件后的字段均建索引 簡(jiǎn)單SQL不需要索引,聯(lián)合查詢才需要索引 聯(lián)合索引的順序是where條件后字段的先后順序 對(duì)于區(qū)分度小的字段上也新建索引,如狀態(tài),性別等字段等。

就一起來聊一聊MySQL索引。

什么是索引?

百度百科是這樣描述的:

索引是為來加速對(duì)表中數(shù)據(jù)行中的檢索而創(chuàng)建的一種分散的數(shù)據(jù)結(jié)果,時(shí)針對(duì)表而建立的,它是由數(shù)據(jù)頁面以外的索引頁面組成,每個(gè)索引頁中的行都含有邏輯指針,以便加速檢索物理數(shù)據(jù)

其實(shí),索引的概念大家都很清楚,也知道索引能夠提升查詢效率,但大部分童鞋在怎么建索引,建在哪些字段上有以下常見誤解:

新建表時(shí)不需要建索引,后續(xù)才添加索引

where條件后的字段均建索引

簡(jiǎn)單SQL不需要索引,聯(lián)合查詢才需要索引

聯(lián)合索引的順序是where條件后字段的先后順序

對(duì)于區(qū)分度小的字段上也新建索引,如狀態(tài),性別等字段等。

索引區(qū)分度

在說上述問題之前,我們先來看看另一個(gè)概念,就是區(qū)分度。

區(qū)分度: 指字段在數(shù)據(jù)庫中的不重復(fù)比

區(qū)分度在新建索引時(shí)有著非常重要的參考價(jià)值,在MySQL中,區(qū)分度的計(jì)算規(guī)則如下:

字段去重后的總數(shù)與全表總記錄數(shù)的商。

例如:

select count(distinct(name))/count(*) from t_base_user;

結(jié)果如下:

count(distinct(name))/count(*)
1.0000

其中區(qū)分度最大值為1.000,最小為0.0000,區(qū)分度的值越大,也就是數(shù)據(jù)不重復(fù)率越大,新建索引效果也越好,在主鍵以及唯一鍵上面的區(qū)分度是最高的,為1.0000。在狀態(tài),性別等字段上面的區(qū)分度值是最小的。 (這個(gè)就要看數(shù)據(jù)量了,如果只有幾條數(shù)據(jù),這時(shí)區(qū)分度還挺高的,如果數(shù)據(jù)量多,區(qū)分度基本為0.0000。也就是在這些字段上添加索引后,效果也不佳的原因。)

值得注意的是:    如果表中沒有任何記錄時(shí),計(jì)算區(qū)分度的結(jié)果是為空值,其他情況下,區(qū)分度值均分布在0.0000-1.0000之間。

如何建索引

(一)  : 區(qū)分度
個(gè)人強(qiáng)烈建議, 建索引時(shí),一定要先計(jì)算該字段的區(qū)分度,原因如下:

1. 單列索引
可以查看該字段的區(qū)分度,根據(jù)區(qū)分度的大小,也能大概知道在該字段上的新建索引是否有效,以及效果如何。區(qū)分度越大,索引效果越明顯。

2.多列索引(聯(lián)合索引)
多列索引中其實(shí)還有一個(gè)字段的先后順序問題,一般是將區(qū)分度較高的放在前面,這樣聯(lián)合索引才更有效,例如:

select * from t_base_user where name="" and status=1;

像上述語句,如果建聯(lián)合索引的話,就應(yīng)該是:

alter table t_base_user add index idx_name_status(name,status);

而不是:

alter table t_base_user add index idx_status_name(status,name);

(二) 最左前綴匹配原則
 MySQL會(huì)一直向右匹配直到遇到范圍查詢(>、<、between、like)就停止匹配,比如

select * from t_base_user where type="10" and created_at<"2017-11-03" and status=1, (該語句僅作為演示)

在上述語句中,status就不會(huì)走索引,因?yàn)橛龅?lt;時(shí),MySQL已經(jīng)停止匹配,此時(shí)走的索引為:(type,created_at),其先后順序是可以調(diào)整的,而走不到status索引,此時(shí)需要修改語句為:

select * from t_base_user where type=10 and status=1 and created_at<"2017-11-03"

即可走status索引。

(三) 函數(shù)運(yùn)算
 不要在索引列上,進(jìn)行函數(shù)運(yùn)算,否則索引會(huì)失效。因?yàn)閎+樹中存的都是數(shù)據(jù)表中的字段值,但進(jìn)行檢索時(shí),需要把所有元素都應(yīng)用函數(shù)才能比較,顯然成本太大。

(四) 擴(kuò)展優(yōu)先
 擴(kuò)展優(yōu)先,不要新建索引,盡量在已有索引中修改。如下:

select * from t_base_user where name="andyqian" and email="andytohome"

在表t_base_user表中已經(jīng)存在idx_name索引,如果需要加入idx_name_email的索引,應(yīng)該是修改idx_name索引,而不是新建一個(gè)索引。

誤解糾正

上面說了,如何新建索引,現(xiàn)在我們就可以來回答,在第一步中存在的誤解了。

誤解一:   新建表時(shí)不需要建立索引,后續(xù)才加索引

答: 一個(gè)好的數(shù)據(jù)表設(shè)計(jì),在一開始就要考慮索引的創(chuàng)建,而不是等到后續(xù)出問題了,影響業(yè)務(wù)使用了,才新建索引來救場(chǎng),而且后續(xù)創(chuàng)建索引的成本也相對(duì)高很多。(這就是給生產(chǎn)事故留下生根發(fā)芽的機(jī)會(huì)呀)

誤解二:   where條件后的字段均建索引

答: 這個(gè)誤解比較常見,但where條件后的字段不需要全部建立索引,過多的索引,也會(huì)導(dǎo)致索引文件劇增,也還達(dá)不到期望中的效果。詳細(xì)請(qǐng)參考上述新建索引的小節(jié)。

誤解三:   簡(jiǎn)單SQL不需要建立索引,聯(lián)合查詢采建立索引

答: 這個(gè)誤解就得好好說說了,現(xiàn)在互聯(lián)網(wǎng)公司特別是B/S架構(gòu)下,業(yè)務(wù)邏輯均剝離在代碼邏輯層,到最后SQL層面,其實(shí)都是一些簡(jiǎn)單的SQL,只有些許連接查詢,更多的還是單表操作,(C/S架構(gòu)中有很多在SQL層面的寫邏輯的),你說這些語句簡(jiǎn)不簡(jiǎn)單。

誤解四:    聯(lián)合索引的順序是where條件后字段的先后順序

答: 我們剛才說過,聯(lián)合索引的順序,是根據(jù)最左前綴原則,以及區(qū)分度來區(qū)分的,和where條件后字段的先后順序無關(guān)。

誤解五: 對(duì)于區(qū)分度較小的字段新建索引

答: 在區(qū)分度較小的字段上新建索引,基本無效,還會(huì)增加大量的索引文件,你說是不是得不償失。

索引重不重要?

上面介紹了MySQL索引的概念,新建索引時(shí)的一些技巧。這么理論的東西,對(duì)于平時(shí)沒有使用或使用比較少的童鞋,此時(shí)對(duì)索引的重要性可能還沒那么直觀,那么,我就來說說我在索引上吃過的虧,踩過的坑!同時(shí)也是未建索引常見問題!

0. 導(dǎo)致慢查詢
這個(gè)問題可是未建索引的??团?,(這里也還有很多細(xì)節(jié)呢,如: 隱式類型轉(zhuǎn)換等等)

1. 導(dǎo)致服務(wù)超時(shí)

場(chǎng)景 :
 在某次上線時(shí),作為服務(wù)提供者,提供服務(wù)給業(yè)務(wù)方使用。一開始以為就提供一個(gè)簡(jiǎn)單的服務(wù),也已經(jīng)測(cè)試完成,心里還在竊喜,今天總算可以早早回家了!

描述 :
 實(shí)際一上線,在生產(chǎn)環(huán)境中導(dǎo)致業(yè)務(wù)方請(qǐng)求調(diào)用時(shí),而且每次請(qǐng)求均超時(shí),數(shù)據(jù)也已落地,此時(shí)只能review代碼,最后發(fā)現(xiàn)生產(chǎn)中有個(gè)慢查詢導(dǎo)致,活活的花費(fèi)了10多秒,這個(gè)語句有多簡(jiǎn)單呢,你絕對(duì)想不到,其實(shí)就是一個(gè)單表的where條件查詢語句。你說這種原因?qū)е路?wù)不可用,你說冤不冤,氣不氣!(這也是我為什么說,一個(gè)好的數(shù)據(jù)表設(shè)計(jì),從一開始就要考慮新建索引了)。

2. 數(shù)據(jù)庫服務(wù)器CPU 100%

在查詢頻率比較高的SQL上,如果由于未建索引,導(dǎo)致慢查詢的話,那可是會(huì)導(dǎo)致數(shù)據(jù)庫服務(wù)器CPU 100%,影響可是整個(gè)系統(tǒng)哦。

小結(jié)
上面說了好幾類,由于沒建立索引而導(dǎo)致的問題,輕則導(dǎo)致慢查詢,影響系統(tǒng)效率,重則,導(dǎo)致CPU 100%,影響整個(gè)系統(tǒng)的使用,看到這里,你說索引重不重要?

最后

上面簡(jiǎn)單說了,索引是什么?有什么用,以及建立索引時(shí)的一些技巧,還著重說了,索引的重要性。那么索引這么重要,在平時(shí)編碼時(shí)如何避免呢?以下是我個(gè)人的建議:

1.在建表時(shí)就應(yīng)該考慮添加索引,如:外鍵字段,等等。

2.在寫完SQL后,一定要查看執(zhí)行計(jì)劃。盡量避免全表掃描。

3.如果是已有表中添加索引,一定要先計(jì)算該字段的區(qū)分度。

4.聯(lián)合索引,將區(qū)分度大放在前面。

5.遵從MySQL左列前綴優(yōu)先原則\

    [2]H. Berenson, P. Bernstein, J. Gray, J.Melton, E. O’Neil,and P. O’Neil. A critique of ANSI SQL isolation levels. InProceedings of the SIGMOD International Conference on Management of Data, pages1–10, May 1995.

    [3]Michael J. Cahill, Uwe R?hm, and Alan D.Fekete. 2008. Serializable isolation for snapshot databases. In SIGMOD ’08:Proceedings of the 2008 ACM SIGMOD international conference on Management of data, pages 729–738, New York, NY, USA. ACM.[4]Michael James Cahill. 2009. Serializable Isolation for Snapshot Databases. Sydney Digital Theses. University of Sydney, School of Information Technologies[5] A. Fekete, D. Liarokapis, E. O’Neil, P.O’Neil, andD. Shasha. Making snapshot isolation serializable. www.codexueyuan.com In ACM transactions on database systems, volume 39(2), pages 492–528, June 2005.


以上是MySQL索引原理是什么的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI