Spring+SpringMVC+MyBatis+easyUI整合優(yōu)化篇(十二)數(shù)據(jù)層優(yōu)化-explain關(guān)鍵字及慢sql優(yōu)化

本文提要

從編碼角度來(lái)優(yōu)化數(shù)據(jù)層的話,我首先會(huì)去查一下項(xiàng)目中運(yùn)行的sql語(yǔ)句润脸,定位到瓶頸是否出現(xiàn)在這里毙驯,首先去優(yōu)化sql語(yǔ)句爆价,而慢sql就是其中的主要優(yōu)化對(duì)象允坚,對(duì)于慢sql稠项,顧名思義就是花費(fèi)較多執(zhí)行時(shí)間的語(yǔ)句展运,它帶來(lái)的影響也比較惡劣拗胜,首先是執(zhí)行時(shí)間過(guò)長(zhǎng)影響數(shù)據(jù)的返回速度埂软,其次勘畔,慢sql的長(zhǎng)時(shí)間執(zhí)行也會(huì)消耗和占用mysql的系統(tǒng)資源炫七,影響其他的sql語(yǔ)句執(zhí)行万哪,過(guò)多的慢sql極其影響性能奕巍,如果系統(tǒng)流量或者并發(fā)量較大的情況下的止,過(guò)多的執(zhí)行慢sql很有可能造成mysql的死鎖以致于mysql服務(wù)無(wú)法正常使用冲杀。
druid整合到項(xiàng)目中以及druid監(jiān)控的開啟已經(jīng)持續(xù)了一段時(shí)間权谁,因此對(duì)于慢sql的監(jiān)控和整理也大致有了一些結(jié)果旺芽,本篇文章就試著從日志文件和監(jiān)控面板中找出幾條慢sql并進(jìn)行優(yōu)化采章。

優(yōu)化步驟

總結(jié)了一下悯舟,大致步驟如下:

  • 定位優(yōu)化對(duì)象的性能瓶頸抵怎;
  • 明確優(yōu)化目標(biāo)反惕;
  • 從explain入手分析姿染;
  • 找到優(yōu)化方法悬赏;

找出慢sql

首先進(jìn)入druid監(jiān)控后臺(tái)舷嗡,查看一下這幾天的運(yùn)行日志后进萄,慢sql的大致情況中鼠,如圖:


慢sql監(jiān)控

從監(jiān)控后臺(tái)看到的數(shù)據(jù)只是一個(gè)粗略的統(tǒng)計(jì)援雇,是一個(gè)總覽記錄,想要看到詳細(xì)的執(zhí)行記錄及其中的慢sql統(tǒng)計(jì)可以通過(guò)日志文件蚕涤,這個(gè)功能也已經(jīng)整合到項(xiàng)目中揖铜,直接在tomcat的logs目錄即可查看天吓。


慢sql日志文件

日志文件內(nèi)容節(jié)選:

//1.圖片表查詢sql
[10:13:37] StatFilter - slow sql 1572 millis. 
select * from ssm_picture
         WHERE  type = ? and grade = ?          
 limit ?,?
["1","1",0,10]

...
//2.更新文章表sql
[14:19:12] StatFilter - slow sql 1926 millis. 
update ssm_article
        set
        article_title=?,article_content=?,
        add_name=?
        where id=?
["11","<p>1324354657usdfghjnkm,zxvb nm,,fgfhjtfggggggggggggggggggg<br/></p>","22","1033"]

...

//3.文章表查詢sql
[15:07:04] StatFilter - slow sql 1672 millis. 
select * from ssm_article
limit ?,?
[0,10]

日志的記錄格式為 [執(zhí)行時(shí)間] -慢sql執(zhí)行耗時(shí) 物邑,sql語(yǔ)句拂封,其實(shí)日志中記錄是挺多的,去重之后從日志文件中單獨(dú)選了幾條比較典型的sql語(yǔ)句進(jìn)行優(yōu)化钟病。

explain關(guān)鍵字

explain關(guān)鍵字一般放在SELECT查詢語(yǔ)句的前面肠阱,用于描述MySQL如何執(zhí)行查詢操作屹徘、以及MySQL成功返回結(jié)果集需要執(zhí)行的行數(shù)噪伊。explain 可以幫助我們分析 select 語(yǔ)句,讓我們知道查詢效率低下的原因,從而改進(jìn)我們查詢,讓查詢優(yōu)化器能夠更好的工作鉴吹。

用法:


explain-01

結(jié)果集說(shuō)明如下:

項(xiàng) 說(shuō)明
id MySQL Query Optimizer選定的執(zhí)行計(jì)劃中查詢的序列號(hào)豆励。表示查詢中執(zhí)行select子句或操作表的順序,id值越大優(yōu)先級(jí)越高,越先被執(zhí)行良蒸。id相同,執(zhí)行順序由上至下。


select_type 查詢類型 說(shuō)明
SIMPLE 簡(jiǎn)單的select查詢,不使用union及子查詢剿吻。
PRIMARY 最外層的select查詢和橙。
UNION UNION 中的第二個(gè)或隨后的 select查詢,不依賴于外部查詢的結(jié)果集魔招。
DEPENDENT UNION UNION中的第二個(gè)或隨后的 select查詢,依 賴于外部查詢的結(jié)果集办斑。
SUBQUERY 子查詢中的第一個(gè)select查詢,不依賴于外部查詢的結(jié)果集乡翅。
DEPENDENT SUBQUERY 子查詢中的第一個(gè)select查詢,依賴于外部查詢的結(jié)果集蠕蚜。
DERIVED 用于from子句里有子查詢的情況靶累。MySQL會(huì)遞歸執(zhí)行這些子查詢,把結(jié)果放在臨時(shí)表里挣柬。
UNCACHEABLE SUBQUERY 結(jié)果集不能被緩存的子查詢,必須重新為外層查詢的每一行進(jìn)行評(píng)估邪蛔。
UNCACHEABLE UNION UNION中的第二個(gè)或隨后的select查詢,屬于不可緩存的子查詢侧到。


項(xiàng) 說(shuō)明
table 輸出行所引用的表


type 顯示連接使用的類型,按最優(yōu)到最差的類型排序 說(shuō)明
system 表僅有一行(=系統(tǒng)表)床牧。這是const連接類型的一個(gè)特例戈咳。
const const用于用常數(shù)值比較PRIMARY KEY時(shí)删铃。當(dāng)查詢的表僅有一行時(shí),使用System猎唁。
eq_ref const用于用常數(shù)值比較PRIMARY KEY時(shí)诫隅。當(dāng)查詢的表僅有一行時(shí),使用System逐纬。
ref 連接不能基于關(guān)鍵字選擇單個(gè)行,可能查找到多個(gè)符合條件的行豁生。叫做ref是因?yàn)樗饕硞€(gè)參考值相比較甸箱。這個(gè)參考值或者是一個(gè)常數(shù),或者是來(lái)自一個(gè)表里的多表查詢的結(jié)果值
ref_or_null 如同ref, 但是MySQL必須在初次查找的結(jié)果里找出null條目,然后進(jìn)行二次查找迅脐。
index_merge 說(shuō)明索引合并優(yōu)化被使用了谴蔑。
unique_subquery 在某些IN查詢中使用此種類型,而不是常規(guī)的ref:value IN (SELECT primary_key FROM single_table WHERE some_expr)
index_subquery 在某些IN查詢中使用此種類型,與unique_subquery類似,但是查詢的是非唯一性索引:value IN(SELECT key_column FROM single_table WHERE some_expr)
range 只檢索給定范圍的行,使用一個(gè)索引來(lái)選擇行树碱。key列顯示使用了哪個(gè)索引成榜。當(dāng)使用=赎婚、<>樱溉、>福贞、>=、<恋技、<=逻族、IS NULL聘鳞、<=>抠璃、BETWEEN或者IN操作符,用常量比較關(guān)鍵字列時(shí),可以使用range。
index 全表掃描,只是掃描表的時(shí)候按照索引次序進(jìn)行而不是行源请。主要優(yōu)點(diǎn)就是避免了排序,但是開銷仍然非常大谁尸。
all 最壞的情況,從頭到尾全表掃描良蛮。


項(xiàng) 說(shuō)明
possible_keys 指出MySQL能在該表中使用哪些索引有助于查詢决瞳。如果為空,說(shuō)明沒(méi)有可用的索引皮胡。


項(xiàng) 說(shuō)明
key MySQL實(shí)際從possible_key選擇使用的索引屡贺。如果為NULL,則沒(méi)有使用索引甩栈。很少的情況下,MYSQL 會(huì)選擇優(yōu)化不足的索引量没。這種情況下,可以在SELECT語(yǔ)句中使用USE INDEX (indexname)來(lái)強(qiáng)制使用一個(gè)索引或者用IGNORE INDEX(indexname)來(lái)強(qiáng)制MYSQL忽略索引


項(xiàng) 說(shuō)明
key_len 使用的索引的長(zhǎng)度殴蹄。在不損失精確性的情況下,長(zhǎng)度越短越好。


項(xiàng) 說(shuō)明
ref 顯示索引的哪一列被使用了


項(xiàng) 說(shuō)明
rows MYSQL認(rèn)為必須檢查的用來(lái)返回請(qǐng)求數(shù)據(jù)的行數(shù)


extra 中出現(xiàn)以下2項(xiàng)意味著MYSQL根本不能使用索引,效率會(huì)受到重大影響漩蟆。應(yīng)盡可能對(duì)此進(jìn)行優(yōu)化怠李。

extra項(xiàng) 說(shuō)明
Using filesort 表示MySQL會(huì)對(duì)結(jié)果使用一個(gè)外部索引排序,而不是從表里按索引次序讀到相關(guān)內(nèi)容捺癞∷杞椋可能在內(nèi)存或者磁盤上進(jìn)行排序唐础。MySQL中無(wú)法利用索引完成的排序操作稱為“文件排序”
Using temporary 表示MySQL在對(duì)查詢結(jié)果排序時(shí)使用臨時(shí)表矾飞。常見(jiàn)于排序order by和分組查詢 group by洒沦。


優(yōu)化目標(biāo)

優(yōu)化的目標(biāo)是一定要明確的申眼,不然根本無(wú)從下手括尸,針對(duì)于前文中提到的sql語(yǔ)句,及explain關(guān)鍵字的解釋钓辆,我列出了兩條目標(biāo):

  • 避免全表掃描
  • rows參數(shù)盡量減小

至于為什么只列出這兩條目標(biāo),主要是因?yàn)轫?xiàng)目中并沒(méi)有復(fù)雜的邏輯娶眷,也也沒(méi)有復(fù)雜的查詢届宠,建表時(shí)也并沒(méi)有根據(jù)相關(guān)查詢創(chuàng)建索引豌注,而且數(shù)據(jù)量也不大轧铁,因此能夠優(yōu)化的點(diǎn)并不是太多齿风,即使做了優(yōu)化也不能顯著的提升速度及性能救斑,因此就先列了兩個(gè)簡(jiǎn)單的小目標(biāo)穷娱,先體驗(yàn)一下explain關(guān)鍵字在sql優(yōu)化中的作用运沦。

優(yōu)化

針對(duì)第2條更新文章sql茶袒,執(zhí)行時(shí)間較長(zhǎng)的原因主要是因?yàn)閿?shù)據(jù)量太大薪寓,應(yīng)該是一個(gè)朋友在測(cè)試的時(shí)候做的操作向叉,article_content字段插入了一條20萬(wàn)字符大小的數(shù)據(jù),因此瘦黑,主要問(wèn)題在于插入數(shù)據(jù)過(guò)大奇唤,代碼已經(jīng)更新了參數(shù)檢查功能甲葬,在程序中做了限制经窖。

對(duì)于另外兩條查詢語(yǔ)句,首先用explain分析sql語(yǔ)句画侣,如下:


ssm_article
ssm_picture

注意其中的兩個(gè)參數(shù)冰悠,type都是all,rows較小配乱,都為總記錄溉卓,我們的兩個(gè)目標(biāo)是什么?type不能為all宪卿,rows盡量小的诵,這里似乎滿足了一個(gè)條件,其實(shí)不然佑钾,因?yàn)檫@兩個(gè)表的數(shù)據(jù)量小西疤,因此rows值也小,如果換一張表(book表較大),以相同格式執(zhí)行一條sql得到如下結(jié)果:


ssm_book

rows為416孽尽,并沒(méi)有因?yàn)槭褂昧薼imit關(guān)鍵字而返回較小的值,因此兩條sql都需要做一下簡(jiǎn)單的優(yōu)化速勇。

幾張表都沒(méi)有創(chuàng)建索引都伪,是不是就沒(méi)有索引了呢磅轻?其實(shí)不然,你可能忽略了一點(diǎn),就是主鍵索引,索引的知識(shí)點(diǎn)在接下來(lái)一篇文章中會(huì)寫,這一篇就簡(jiǎn)單的提一下,因此優(yōu)化策略就是使用主鍵索引,將type由all變?yōu)閕ndex,稍微優(yōu)化了一點(diǎn)點(diǎn),改寫后的sql語(yǔ)句如下,分析結(jié)果如下:


ssm_book

通過(guò)與上面的結(jié)果對(duì)比损话,可以看到rows值也變小了。


ssm_picture
ssm_article

type由all全部變?yōu)閕ndex齐佳。

總結(jié)

由于項(xiàng)目比較簡(jiǎn)單,都是操作單表的sql語(yǔ)句,沒(méi)有復(fù)雜查詢,也沒(méi)有多表的連接查詢,速度提升并沒(méi)有太多,對(duì)于目前的項(xiàng)目來(lái)說(shuō),不會(huì)有特別大的優(yōu)化動(dòng)作歹苦,如果以后有機(jī)會(huì)再去結(jié)合實(shí)際案例去優(yōu)化,現(xiàn)在就點(diǎn)到為止了,這一篇主要是介紹一下druid監(jiān)控的成果以及mysql查詢優(yōu)化的explain關(guān)鍵字悠砚,因此并沒(méi)有做太多的案例及分析,只是做了一些小修改别智,使得大家對(duì)explain關(guān)鍵字有了一些了解,下一篇會(huì)繼續(xù)做一些優(yōu)化改動(dòng)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辈挂,一起剝皮案震驚了整個(gè)濱河市矮锈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖蝌麸,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異攒驰,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)棺克,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)鉴竭,“玉大人,你說(shuō)我怎么就攤上這事泰演⊥嗫唬” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵纸俭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我膘融,道長(zhǎng)臼疫,這世上最難降的妖魔是什么湾盗? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮悔醋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嘁捷。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著忽冻,像睡著了一般蝗碎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上笑窜,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音猜年,去河邊找鬼撇簿。 笑死诚纸,一個(gè)胖子當(dāng)著我的面吹牛畦徘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播抬闯,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼井辆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了画髓?” 一聲冷哼從身側(cè)響起掘剪,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤平委,失蹤者是張志新(化名)和其女友劉穎奈虾,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體廉赔,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肉微,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蜡塌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碉纳。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖馏艾,靈堂內(nèi)的尸體忽然破棺而出劳曹,到底是詐尸還是另有隱情奴愉,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布铁孵,位于F島的核電站锭硼,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蜕劝。R本人自食惡果不足惜檀头,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望岖沛。 院中可真熱鬧暑始,春花似錦、人聲如沸婴削。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)馆蠕。三九已至期升,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間互躬,已是汗流浹背播赁。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吼渡,地道東北人容为。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像寺酪,于是被迫代替她去往敵國(guó)和親坎背。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容