MySQL優(yōu)化實(shí)踐3筆記

本文為Percona的Practical MySQL Performance Optimization第3節(jié)的筆記,基礎(chǔ)知識(shí)為主。

索引

InnoDB和MyISAM都支持B-tree索引,可以支持快速的相等查詢(例如id = 1)和范圍查詢(例如>、<和in)。InnoDB的主鍵索引還是聚簇的,數(shù)據(jù)和主鍵放一起,獲取數(shù)據(jù)會(huì)更快。

B-tree

索引使用

explain可以查看MySQL對(duì)一個(gè)語句的執(zhí)行計(jì)劃,其中的key是查詢使用的索引。

MySQL查詢的時(shí)候只會(huì)對(duì)每個(gè)表用一個(gè)索引,而且只用這個(gè)索引的最左前綴。

例如對(duì)一個(gè)三個(gè)字段組成的組合索引Comb(CountryCode, District, Population)

MySQL可以用下面這3個(gè)部分:

  • 只用CountryCode部分
  • 只用CountryCode + District部分
  • CountryCode + District + Population全部

組合索引中各部分的順序也會(huì)影響查詢,最好是先比較相等的字段,再到范圍字段。

先比較相等,再做范圍查詢,減少掃描行數(shù)

查詢計(jì)劃中可以根據(jù)key_len或JSON格式的查詢計(jì)劃中used_key_parts來判斷用了索引的那個(gè)部分。

覆蓋索引就是覆蓋了一個(gè)查詢中Select、Where、Group by、Order by出現(xiàn)的全部字段的索引。

查詢

Group by優(yōu)化

沒有索引的情況下要掃描整個(gè)表,還會(huì)用臨時(shí)表存放結(jié)果。

篩選條件是相等比較時(shí),用包含篩選條件和Group by字段的組合索引(或覆蓋索引),可以避免臨時(shí)表。(效果類似上面的圖,先通過篩選條件的索引找到Group的索引,根據(jù)Group的索引知道Group的個(gè)數(shù)和數(shù)據(jù)的位置,然后對(duì)每個(gè)Group掃描就可以了)。

如果篩選條件是范圍查詢,可以已通過union改成多個(gè)查詢合并,來減少臨時(shí)表的大?。總€(gè)查詢不用臨時(shí)表,但最后合并要)。

在對(duì)一個(gè)表進(jìn)行Group by,Group by條件只包含索引的最左前綴,而且只用max/min對(duì)這個(gè)索引的前綴進(jìn)行聚合運(yùn)算,MySQL可以進(jìn)行松散的索引掃描,只用掃描少部分的索引,很快。(應(yīng)該是索引里直接保存了max/min的結(jié)果來減少對(duì)一課子樹的掃描)。

Order by優(yōu)化

Order by查詢數(shù)據(jù)多的時(shí)候要進(jìn)行文件排序,而索引是已經(jīng)排序的,可以避免文件排序,Limit條數(shù)較少也可以避免文件排序。

計(jì)算表達(dá)式

如果查詢條件里有函數(shù),MySQL是不能用函數(shù)參數(shù)上的索引快速篩選的,這時(shí)通常要用單獨(dú)的一列保存函數(shù)調(diào)用的結(jié)果,但是要在應(yīng)用層或觸發(fā)器保證正確更新。MySQL 5.7有了虛擬/生成字段,可以直接在一個(gè)虛擬字段里保存函數(shù)調(diào)用的結(jié)果,虛擬字段不會(huì)被保存,但是可以建索引!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容