MySQL中復(fù)合索引和覆蓋索引的區(qū)別詳解
前言準(zhǔn)備
我們先準(zhǔn)備一張表和幾個(gè)字段,方便介紹覆蓋索引和復(fù)合索引。
創(chuàng)建一個(gè)user表,表中有id、name、school、age字段。
字段名 | 字段類(lèi)型 |
id | int |
name | varchar |
school | varchar |
age | int |
復(fù)合索引
先來(lái)說(shuō)復(fù)合索引,復(fù)合索引是一種索引,它包含多個(gè)字段,復(fù)合索引能夠使一個(gè)SQL查詢(xún)多個(gè)條件時(shí)也能走索引,提高查詢(xún)性能。
比如,創(chuàng)建一個(gè)name、school和age的復(fù)合索引:
CREATE INDEX idx_name_school_age ON user(name, school, age);
查詢(xún)SQL為:
select * from user where name = '張三' and school = '北京大學(xué)' and age > 18
注意,在這里要注意查詢(xún)條件的順序要按照復(fù)合索引的字段順序,要是不按照復(fù)合索引的順序,通常情況下是不會(huì)走索引的,因?yàn)閺?fù)合索引是按照最左匹配原則,最左匹配原則的意思是查詢(xún)條件的順序要按照復(fù)合索引字段順序。
為什么要說(shuō)通常情況下不走索引呢,是因?yàn)镸ySQL的查詢(xún)優(yōu)化器會(huì)根據(jù)條件查詢(xún)和數(shù)據(jù)分布情況選擇最優(yōu)的執(zhí)行計(jì)劃,假設(shè),我們把school和name的查詢(xún)條件到換一下,變成:
select * from user where school = '北京大學(xué)' and name = '張三' and age > 18
如果,我們條件中的school的值非常稀疏,name和age的值非常密集,那么MySQL在查詢(xún)時(shí)會(huì)認(rèn)為使用索引能夠加速查詢(xún),也會(huì)使用索引。
這里,有些同學(xué)可能會(huì)對(duì)稀疏和密集這兩個(gè)詞有些困惑,不明白這兩個(gè)詞的意思,在這里要單獨(dú)拿出來(lái)說(shuō)一下,下面往user表中增加五條數(shù)據(jù),做為案例數(shù)據(jù):
id | name | school | age |
1 | 張三 | 北京大學(xué) | 18 |
2 | 李四 | 北京大學(xué) | 18 |
3 | 王五 | 清華大學(xué) | 18 |
4 | 趙六 | 北京大學(xué) | 18 |
5 | 金七 | 清華大學(xué) | 18 |
稀疏的意思是每個(gè)不同的值出現(xiàn)的次數(shù)很多,比如說(shuō)user表中有五條記錄,name字段分別有張三、李四、王五、趙六、金七,那么我們就可以說(shuō)name這個(gè)字段非常稀疏;
那么相反,密集就好理解了,比如,user表school字段的值分別只有北京大學(xué)和清華大學(xué),那么就可以說(shuō)school字段的值非常密集。
總之,MySQL的查詢(xún)優(yōu)化器會(huì)根據(jù)條件查詢(xún)和數(shù)據(jù)分布情況選擇最優(yōu)的執(zhí)行計(jì)劃,并不是說(shuō)我們不按照復(fù)合索引的字段順序做查詢(xún)條件就不會(huì)走復(fù)合索引。
覆蓋索引
覆蓋索引是一種索引優(yōu)化手段,假設(shè),我們想查詢(xún)user表中name等于張三,獲取張三的school和age字段數(shù)據(jù),那么我們的SQL應(yīng)該是:
slelect school, age from user where name = '張三'
那么,為了優(yōu)化這個(gè)查詢(xún)SQL,我們就需要?jiǎng)?chuàng)建一個(gè)復(fù)合索引,復(fù)合索引中有name、school和age字段:
CREATE INDEX idx_name_school_age ON user(name, school, age);
當(dāng)我們查詢(xún)SQL時(shí),MySQL就可以直接從索引中獲取所需要的數(shù)據(jù),不需要再回表查詢(xún)數(shù)據(jù)了,這樣就能大大的提高查詢(xún)速度。
在這里介紹一下回表: 假設(shè),我們創(chuàng)建一個(gè)復(fù)合索引,復(fù)合索引中有name和age字段:
CREATE INDEX idx_name_school_age ON user(name, age);
我們這里寫(xiě)一個(gè)查詢(xún)SQL,SQL中查詢(xún)name等于張三的school和age字段值:
slelect school, age from user where name = '張三'
那么在查詢(xún)時(shí),SQL語(yǔ)句會(huì)直接查詢(xún)索引,從索引中查詢(xún)到name叫做張三的數(shù)據(jù)位置,再根據(jù)位置去表中查詢(xún)完整的數(shù)據(jù),這里,根據(jù)位置去表中查詢(xún)完整的數(shù)據(jù)叫做回表。
總結(jié)
覆蓋索引和復(fù)合索引的區(qū)別是:覆蓋索引是一種索引優(yōu)化技術(shù),而復(fù)合索引是一種索引。
使用復(fù)合索引時(shí)應(yīng)該注意查詢(xún)SQL條件的順序,以及要避免回表,從而影響到查詢(xún)效率。
到此這篇關(guān)于MySQL中復(fù)合索引和覆蓋索引的區(qū)別詳解的文章就介紹到這了,更多相關(guān)MySQL復(fù)合索引和覆蓋索引內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL OOM 系統(tǒng)二 OOM Killer
前面一節(jié)重點(diǎn)分享了Linux的內(nèi)存分配策略,基于上述的分配策略,為了規(guī)避超售的風(fēng)險(xiǎn),Linux采了一種OOM Killer的機(jī)制,即系統(tǒng)可用內(nèi)存(包括Swap)即將使用完之前,選擇性的Kill掉一些進(jìn)程以求釋放一些內(nèi)存2016-07-07用命令創(chuàng)建MySQL數(shù)據(jù)庫(kù)(de1)的方法
下面小編就為大家?guī)?lái)一篇用命令創(chuàng)建MySQL數(shù)據(jù)庫(kù)(de1)的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03PowerDesigner連接MySQL數(shù)據(jù)庫(kù)的詳細(xì)步驟
這篇文章主要介紹PowerDesigner連接MySQL數(shù)據(jù)庫(kù)的詳細(xì)步驟,文章通過(guò)圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)PowerDesigner連接MySQL數(shù)據(jù)庫(kù)有一定的幫助,需要的朋友可以參考下2023-09-09MySQL中設(shè)置服務(wù)器級(jí)別的默認(rèn)排序規(guī)則的方法
collation_server?是一個(gè)系統(tǒng)變量,它定義了服務(wù)器級(jí)別的默認(rèn)排序規(guī)則,本文主要介紹了MySQL中設(shè)置服務(wù)器級(jí)別的默認(rèn)排序規(guī)則的方法,具有一定的參考價(jià)值,感興趣的可以了解一下2024-08-08MySQL數(shù)據(jù)庫(kù)自動(dòng)補(bǔ)全命令的三種方法
這篇文章主要介紹了MySQL數(shù)據(jù)庫(kù)自動(dòng)補(bǔ)全命令的三種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02MYSQL大小寫(xiě)不敏感導(dǎo)致用戶(hù)登錄異常問(wèn)題
這篇文章主要介紹了MYSQL大小寫(xiě)不敏感導(dǎo)致用戶(hù)登錄異常問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04