在進(jìn)行性能分析前锨苏,需要先定位耗時(shí)查詢婆赠。
MySQL提供了內(nèi)建的耗時(shí)查詢?nèi)罩玖臃弧J褂们罢蜷_my.cnf文件,將slow_query_log設(shè)置為"On"旧乞。 同時(shí)將long_query_time設(shè)置為一個(gè)對(duì)一次查詢來說比較慢的時(shí)間(秒數(shù))蔚润,比如0.2。slow_query_log_file設(shè)置為你想保存日志文件的路徑尺栖。然后運(yùn)行代碼嫡纠,執(zhí)行時(shí)間超過設(shè)定上限的查詢將會(huì)被記錄到日志中。
一旦定位這些煩人的查詢延赌,就可以探究慢的原因除盏。MySQL提供了EXPLAIN關(guān)鍵字〈煲裕可以與SELECT者蠕、DELETE、INSERT掐松、REPLACE踱侣、UPDATE語句一起使用。只需要如下一樣添加到查詢開始處:
EXPLAIN?SELECT?picture.id,?picture.title
FROM?picture
LEFT?JOIN?album?ON?picture.album_id?=?album.idWHERE?album.user_id?=?1;
結(jié)果是對(duì)數(shù)據(jù)訪問過程的解析大磺。每行代表一個(gè)查詢相關(guān)的數(shù)據(jù)表:
重點(diǎn)是表名抡句、使用的key、查詢執(zhí)行時(shí)所掃描的行數(shù)杠愧。
這個(gè)查詢掃描了picture表2百萬行待榔,對(duì)每個(gè)picture記錄掃描了album表2萬行。意味著流济,該查詢實(shí)際掃描了album表400億行锐锣。這個(gè)過程可以更高效腌闯。
索引
使用索引,可以極大提升性能雕憔。比如地址簿中的名字绑嘹。找一個(gè)名字,你可以從頭翻到尾橘茉,也可以找到相應(yīng)的字符標(biāo)簽頁(yè)來快速定位。
使用索引可以避免無必要的表掃描姨丈。比如在picture.album_id上添加索引:
ALTER?TABLE?picture?ADD?INDEX(album_id);
現(xiàn)在執(zhí)行查詢畅卓,就不會(huì)掃描整個(gè)picture列表了。首先蟋恬,所有的album表會(huì)被掃描以找到屬于該用戶的album翁潘,然后,使用album_id列索引快速定位對(duì)應(yīng)的picture歼争。掃描的行數(shù)減少到了20萬拜马,比原始查詢快了317倍。
按照以下方式添加索引可以確保兩張表都能使用對(duì)應(yīng)鍵:
ALTER?TABLE?album?ADD?INDEX(user_id);
這次沐绒,album表不會(huì)被全部掃描俩莽,通過user_id鍵就可以精確定位相應(yīng)的album。然后這100個(gè)album被掃描后乔遮,通過album_id鍵相關(guān)的picture也可以快速找到扮超。每張表都用到了一個(gè)鍵進(jìn)行查詢性能優(yōu)化,結(jié)果比原始查詢快了380倍蹋肮。
但是并不意味著可以隨意添加索引出刷,因?yàn)樗饕龝?huì)導(dǎo)致寫數(shù)據(jù)庫(kù)用時(shí)增長(zhǎng)。所以使用索引導(dǎo)致讀用時(shí)縮短坯辩,寫用時(shí)增長(zhǎng)馁龟。因此,如果能提升讀性能時(shí)再添加索引漆魔。使用EXPLAIN來確認(rèn)索引是否被查詢用到坷檩,沒有就刪除。