掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
前面幾篇文章和小伙伴們聊的基本上都是從索引的角度去優(yōu)化 MySQL 查詢,然而,索引創(chuàng)建的好,并不意味著查詢就一定快,影響查詢效率的因素特別多,今天我們就來聊一聊這些可能影響到查詢的因素。

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、重慶小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了城區(qū)免費(fèi)建站歡迎大家使用!
開始今天的內(nèi)容之前,先來和小伙伴們大概捋一捋 MySQL 的查詢流程。我們來看如下一張圖:
這張圖大家大概有個(gè)印象,在后續(xù)的 MySQL 查詢和優(yōu)化中,很多東西就容易理解了。
接下來我們就來看看什么情況下查詢會(huì)變慢。
數(shù)據(jù)按需取用。有時(shí)候我們會(huì)忽略多拿數(shù)據(jù)對(duì)查詢性能的影響,然而優(yōu)化是一個(gè)錙銖必較的事情,需要多少數(shù)據(jù)就查詢多少,要盡量避免數(shù)據(jù)庫查詢 100 條,結(jié)果前端只展示 10 條這種情況。如有需要,可以通過 limit 來限制數(shù)據(jù)庫查詢出來的數(shù)據(jù)總量。
如果在查詢的時(shí)候使用了唯一性索引的話,那么查詢到記錄之后 MySQL 就停止掃描了;但是如果查詢的時(shí)候使用的是非唯一性索引的話,那么掃描到第一條記錄之后,還會(huì)繼續(xù)向后掃描,直到掃描到第一條不滿足條件的記錄為止,對(duì)于這種情況,如果我們確定查詢的結(jié)果只有一條,則可以通過 limit 進(jìn)行限制,設(shè)置 limit 1,那么掃描到第一條滿足條件的記錄之后,就不會(huì)繼續(xù)掃描了。
查詢的時(shí)候盡量避免 select *,這個(gè)問題在之前的文章中松哥其實(shí)和大家聊過了,因?yàn)楹芏鄷r(shí)候我們?cè)谇岸似鋵?shí)并不需要使用到那么多字段,可能只是為了查詢簡(jiǎn)單,直接來一個(gè) select *,有時(shí)候列數(shù)和數(shù)據(jù)總量都比較少的時(shí)候,這么寫也看不出來性能明顯的差異,但是當(dāng)列數(shù)和數(shù)據(jù)量大了,那么 select * 帶來的影響就會(huì)比較大了。
特別是有的時(shí)候多表聯(lián)合查詢,如果用 select * 就會(huì)把多張表的查詢結(jié)果拼接到一起,那么此時(shí)查詢結(jié)果的列數(shù)就會(huì)成倍增加。
在前面的文章中,松哥也和大家提到過覆蓋索引,如果索引設(shè)計(jì)得當(dāng),那么在查詢的時(shí)候可以通過覆蓋索引來提高查詢的性能,但是如果使用了 select * 那么大概率是用不了覆蓋索引了。
這里舉一個(gè) TienChin 項(xiàng)目的例子,用戶登錄成功之后,在后續(xù)的流程中,經(jīng)常會(huì)用到當(dāng)前登錄用戶的信息,如果每次都去數(shù)據(jù)庫查詢,每次查詢返回結(jié)果都是一致的,沒有必要,此時(shí)我們可以將用戶信息存入到 Redis 緩存中,需要的時(shí)候從 Redis 中提取就可以了。
在項(xiàng)目中,對(duì)于這些需要多次頻繁查詢,且每次查詢返回結(jié)果一樣的數(shù)據(jù),都可以選擇將之存入到緩存中以提高查詢性能。
在查詢的時(shí)候,我們可以通過 explain 來查看執(zhí)行計(jì)劃,執(zhí)行計(jì)劃中有一個(gè)指標(biāo)是掃描行數(shù),如下圖中的 rows,這個(gè)就表示查詢優(yōu)化器預(yù)估要掃描多少行記錄,filtered 則表示預(yù)估滿足條件的比例。
一般在單表查詢時(shí)候我們并不會(huì)特別關(guān)注 filtered 字段,在多表聯(lián)合查詢的時(shí)候會(huì)比較關(guān)注該字段的值。
這一條實(shí)際上就是讓大家關(guān)注前面查詢計(jì)劃中的 type 字段的值,type 字段的取值有很多種,例如常見的 index、ALL、range、const 以及 ref,還有一些不常見的如 system、eq_ref、fulltext、ref_or_null、index_merge、unique_subquery、index_subquery 等,每一種都代表了不同的查詢計(jì)劃,再結(jié)合查詢計(jì)劃中的 Extra 字段中的值,我們大致上可以將查詢分為三種類型:

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流