SQL調(diào)優(yōu)

一红淡、SQL調(diào)優(yōu)的依據(jù) - 測(cè)試

二坐儿、優(yōu)化性能的三架馬車

2.1 DDL設(shè)計(jì)優(yōu)化

整體原則是根據(jù)系統(tǒng)將要進(jìn)行的查詢來設(shè)計(jì)schema碎税。

1)選擇合適的數(shù)據(jù)類型:原則是1??選擇夠用的最小數(shù)據(jù)類型伯襟,好處是占用磁盤、內(nèi)存晃择、CPU緩存空間少冀值,處理時(shí)需要的CPU周期也少;2??優(yōu)先使用簡單類型宫屠,如整型比字符操作代價(jià)低列疗。

具體來說,1??主鍵列優(yōu)先選擇整數(shù)類型浪蹂,速度快且可使用auto increment抵栈;2??用于聯(lián)表查詢的關(guān)聯(lián)列,如film表的filmId和actor表的filmID坤次,無論是否設(shè)置外鍵古劲,推薦使用相同的類型,以避免比較操作時(shí)的類型轉(zhuǎn)換缰猴;3??盡量指定列為not null产艾,尤其是要建索引的列;如果查詢中包含可為null的列滑绒,其索引闷堡,索引統(tǒng)計(jì),值比較更加復(fù)雜難以優(yōu)化疑故。

2)考慮DDL設(shè)計(jì)的范式與反范式:

范式的好處:1)避免冗余數(shù)據(jù)杠览;2)數(shù)據(jù)表更小可加載到內(nèi)存;3)查詢中更少的使用使用group by和distinct等開銷大的查詢焰扳;缺點(diǎn)是需要大量聯(lián)表操作倦零,通常我們需要控制單個(gè)查詢的聯(lián)表數(shù)目不超過12個(gè)表误续,想起來太陽公司的extract customer大sql吨悍。

反范式的好處:1)避免聯(lián)表;2)更有效的索引策略蹋嵌,如select msgContent from msg join user on userID where user.type=‘vip’ order by msg.published desc limit 10育瓜,索引是msg.published。執(zhí)行計(jì)劃是掃描msg.published索引栽烂,對(duì)每條msg數(shù)據(jù)去user表查看是否vip用戶躏仇,如果vip用戶少則效率低下恋脚;如果是一張表,則用(published, usertype)作為索引可以提升查詢效率焰手。缺點(diǎn)是:1)數(shù)據(jù)冗余糟描;2)數(shù)據(jù)表更大,通常我們需要控制列數(shù)不能達(dá)到數(shù)百列书妻,因?yàn)榉?wù)層和引擎層之間通過‘行緩沖‘拷貝數(shù)據(jù)船响,服務(wù)層把行數(shù)據(jù)解碼成各個(gè)列,列越多則開銷越大躲履。

2.2 索引設(shè)計(jì)優(yōu)化

索引可以提高查詢见间、排序操作的效率。

1)作為開發(fā)工猜,理解什么樣的查詢可以應(yīng)用已有索引米诉。設(shè)計(jì)索引的時(shí)候需要考慮后續(xù)的查詢;后續(xù)設(shè)計(jì)查詢的時(shí)候也需要考慮應(yīng)用已有的索引篷帅。就是兩邊都一起努力史侣,希望盡可能多的查詢操作能夠通過索引完成。

2)Mysql本身魏身,提供自適應(yīng)哈希索引抵窒、聚簇索引、覆蓋索引進(jìn)一步提高查詢效率叠骑。

索引設(shè)計(jì)的注意事項(xiàng)

1)多列索引優(yōu)于多個(gè)單列索引:不建議為每個(gè)列單獨(dú)創(chuàng)建索引李皇,例如對(duì)姓/名/生日分別建立索引,當(dāng)根據(jù)姓/名查詢時(shí)宙枷,mysql同時(shí)使用這兩個(gè)單列索引進(jìn)行掃描掉房,并將結(jié)果合并,合并算法包括與/或慰丛,稱為索引合并卓囚,索引合并也是索引設(shè)計(jì)的壞味道。

2)合理的索引列順序:通常將選擇性更強(qiáng)的列放在前面诅病,將用于范圍查詢的列放在后面哪亿。索引的選擇越強(qiáng)則索引查詢效率越高。索引的選擇性指不重復(fù)的索引值和數(shù)據(jù)表總量的比值贤笆,主鍵索引的選擇性最強(qiáng)蝇棉;如果查詢條件中的索引值(如null)搜索出1萬多條數(shù)據(jù),就是典型的選擇性差芥永,此時(shí)索引查詢對(duì)于讀操作的效率提升幫助較写垡蟆;再比如埋涧,未登錄用戶的用戶名均為guest板辽,涉及guest用戶的查詢與正常用戶查詢性能相距甚遠(yuǎn)奇瘦。

索引維護(hù)的注意事項(xiàng)

1)刪除重復(fù)索引和冗余索引:重復(fù)索引是在相同的列上按照相同順序創(chuàng)建的相同類型索引,如索引(A)和索引(A)劲弦。索引(A,B)和索引(A)是冗余索引耳标,因?yàn)楹笳呤乔罢叩淖箧I索引。

2)刪除未使用索引

3)減少索引碎片:B+Tree的葉子節(jié)點(diǎn)的物理分布不是連續(xù)的邑跪,InnoDB提供添加/刪除索引功能麻捻,可以通過先刪除,再創(chuàng)建的方式消除索引的碎片化呀袱。

2.3 查詢語句優(yōu)化

2.3.1 時(shí)間都去哪兒了贸毕?

性能是完成某任務(wù)的時(shí)間度量,也就是響應(yīng)時(shí)間夜赵;優(yōu)化查詢性能就是提高查詢的響應(yīng)速度明棍。響應(yīng)時(shí)間包括執(zhí)行時(shí)間和等待時(shí)間,等待時(shí)間又包括等待IO和等待鎖的時(shí)間寇僧。那么查詢的時(shí)間都花在哪兒了呢摊腋?我們可以通過show full processlist查看線程狀態(tài)進(jìn)而查看查詢的生命周期:

1)Sleep:等待客戶端發(fā)送請(qǐng)求;2)Query:正在執(zhí)行查詢嘁傀,或者正在返回結(jié)果給客戶端兴蒸;3)Locked:在服務(wù)器層等待表鎖,等待InnoDB的行鎖并不會(huì)在此顯示细办;4)analysing & statistices:正在收集存儲(chǔ)引擎統(tǒng)計(jì)信息橙凳,生成執(zhí)行計(jì)劃;5)Copying to temp table(on disk):正在執(zhí)行查詢并把結(jié)果復(fù)制到臨時(shí)表笑撞,在group by岛啸、文件排序和union等操作出現(xiàn);6)sorting result:正在排序茴肥;7)Sending data:在多個(gè)狀態(tài)間傳送數(shù)據(jù)坚踩,或者正在生成結(jié)果集,或者向客戶端返回?cái)?shù)據(jù)瓤狐;


2.3.2?查詢優(yōu)化的思路

1)客戶端是否向數(shù)據(jù)庫請(qǐng)求了不需要的數(shù)據(jù):1. 可使用limit減少返回的行瞬铸;2. 可通過避免使用select * 減少返回的列,但有時(shí)select * 配合緩存總體性能也不錯(cuò)础锐;3. 通過緩存避免重復(fù)查詢相同的數(shù)據(jù)嗓节。

2)通過日志中記錄的掃描行數(shù)和返回行數(shù),查看服務(wù)端是否掃描了不需要的數(shù)據(jù)郁稍。理想情況下赦政,掃描行數(shù)等于返回行數(shù)胜宇;但聯(lián)表查詢時(shí)掃碼多行才能連結(jié)為一行返回耀怜,掃描行數(shù)會(huì)明顯大于返回行數(shù)恢着。Where條件對(duì)應(yīng)的3種處理方式,掃描行數(shù)從少到多依次是:1. 索引作為查詢條件财破,在存儲(chǔ)引擎層完成掰派;2. 索引覆蓋掃描(using index),服務(wù)層直接從索引中過濾掉不需要的數(shù)據(jù)左痢;3. 服務(wù)層過濾不滿足條件的記錄(using where)靡羡。


更多內(nèi)容詳見:http://www.reibang.com/p/b2d20d93857c

三、優(yōu)化器有所為有所不為

3.1 有所為

1)關(guān)聯(lián)表順序重排俊性,對(duì)于join略步;2)min/max函數(shù)優(yōu)化,基于B+Tree定页;3)提前終止查詢趟薄,如limit;4)in子句優(yōu)化典徊;5)表達(dá)式等價(jià)轉(zhuǎn)換杭煎;6)把子查詢優(yōu)化掉;7)將外連接轉(zhuǎn)化為內(nèi)連接:outer/inner join

3.2 有所不為

1)避免在in中包含子查詢卒落;2)優(yōu)化器不考慮并發(fā)羡铲,也無法利用多核特定來并行執(zhí)行查詢;3)當(dāng)在同一個(gè)表上查詢和更新時(shí)儡毕,通過用as生成臨時(shí)表的方式來解決也切。

四、分析工具

4.1 執(zhí)行計(jì)劃

Mysql優(yōu)化器基于成本選擇最優(yōu)執(zhí)行計(jì)劃并交給執(zhí)行引擎腰湾,執(zhí)行計(jì)劃采用指令樹的形式贾费。用戶可以用explain命令請(qǐng)求優(yōu)化器解釋優(yōu)化過程,查看生成的執(zhí)行計(jì)劃檐盟。

min/max函數(shù)優(yōu)化:1. 能夠使用索引時(shí)褂萧,通過查找B-tree的最左端/最右端優(yōu)化min/max函數(shù);執(zhí)行計(jì)劃顯示select tables optimized away葵萎,表示優(yōu)化器已經(jīng)在執(zhí)行計(jì)劃中把該表移除导犹,用常數(shù)取代;

需要服務(wù)層進(jìn)行篩選的查詢羡忘,執(zhí)行計(jì)劃的extra顯示為using where谎痢。例如select id from user where id<5 and id <>1; innoDB鎖定id為1-4的數(shù)據(jù)并返回給服務(wù)器層,服務(wù)器層繼而過濾掉id=1卷雕;執(zhí)行計(jì)劃的extra顯示using where节猿。

使用覆蓋索引時(shí)執(zhí)行計(jì)劃的extra為using index

當(dāng)通過執(zhí)行計(jì)劃看到對(duì)多個(gè)索引做and運(yùn)算時(shí),說明需要一個(gè)多列索引滨嘱。

聯(lián)表查詢的排序:建議order by中所有的列來自于同一張表峰鄙;如果order by中所有列來自第一個(gè)表,則查詢第一張表時(shí)就進(jìn)行排序太雨,執(zhí)行計(jì)劃顯示using filesort吟榴;否則mysql把查詢結(jié)果放到臨時(shí)表,在關(guān)聯(lián)查詢結(jié)束后進(jìn)行排序囊扳,執(zhí)行計(jì)劃顯示using temporary using filesort吩翻。

4.2 常見命令

1)show status:輸出是計(jì)數(shù),如created_tmp_tables計(jì)數(shù)器值為3表示創(chuàng)建3個(gè)臨時(shí)表锥咸;handler_read_rnd_next計(jì)數(shù)器值為6478表示有很多沒用到索引的讀操作狭瞎,出現(xiàn)在多表關(guān)聯(lián)查詢,子查詢創(chuàng)建了臨時(shí)表搏予,臨時(shí)表沒有索引脚作;

2)show profile:輸出一個(gè)查詢的各個(gè)子步驟所花費(fèi)時(shí)間,比如等待鎖缔刹、優(yōu)化器優(yōu)化球涛、生成臨時(shí)表、排序校镐;

3)information_schema.index_statistics:用于查看索引使用頻率并刪除未使用的索引亿扁,統(tǒng)計(jì)數(shù)據(jù)來源于InnoDB記錄索引訪問并保存索引統(tǒng)計(jì)信息。

4)show full processlist查看線程狀態(tài)進(jìn)而查看查詢的生命周期鸟廓。

4.3 慢日志查詢

把效率低的查詢捕獲到文件

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末从祝,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子引谜,更是在濱河造成了極大的恐慌牍陌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件员咽,死亡現(xiàn)場(chǎng)離奇詭異毒涧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)贝室,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門契讲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人滑频,你說我怎么就攤上這事捡偏。” “怎么了峡迷?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵银伟,是天一觀的道長。 經(jīng)常有香客問我,道長彤避,這世上最難降的妖魔是什么傅物? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮忠藤,結(jié)果婚禮上挟伙,老公的妹妹穿的比我還像新娘楼雹。我一直安慰自己模孩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布贮缅。 她就那樣靜靜地躺著榨咐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谴供。 梳的紋絲不亂的頭發(fā)上块茁,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音桂肌,去河邊找鬼数焊。 笑死,一個(gè)胖子當(dāng)著我的面吹牛崎场,可吹牛的內(nèi)容都是我干的佩耳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼谭跨,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼干厚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起螃宙,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤蛮瞄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后谆扎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挂捅,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年堂湖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了籍凝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡苗缩,死狀恐怖饵蒂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情酱讶,我是刑警寧澤退盯,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響渊迁,放射性物質(zhì)發(fā)生泄漏慰照。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一琉朽、第九天 我趴在偏房一處隱蔽的房頂上張望毒租。 院中可真熱鬧,春花似錦箱叁、人聲如沸墅垮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽算色。三九已至,卻和暖如春螟够,著一層夾襖步出監(jiān)牢的瞬間灾梦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國打工妓笙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留若河,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓寞宫,卻偏偏與公主長得像萧福,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子淆九,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355