MySQL性能調(diào)優(yōu)
后端程序員在面試中,經(jīng)常會(huì)被問到SQL調(diào)優(yōu)的操作,于是我也是去補(bǔ)習(xí)了一下這方面的知識(shí),感謝各方大佬提供的點(diǎn)子,這里總結(jié)如下。
總結(jié)幾點(diǎn)常見的誤區(qū):
1-?count(1)和count(primary_key)并不優(yōu)于count(*);
2-?count(*)和count(column)是不一樣的。count(*)表示整個(gè)結(jié)果集有多少記錄,count(column)表示結(jié)果集中有多少個(gè)column字段不為空的記錄。
3-?通常來(lái)說(shuō),把可以為NULL的列改為NOT NULL不會(huì)對(duì)性能提升有多少幫助,只是如果計(jì)劃在列上創(chuàng)建索引,就應(yīng)該將該列設(shè)置為NOT NULL。
4-?對(duì)整數(shù)類型指定寬度,比如INT(11),沒有任何作用。INT使用32位(4個(gè)字節(jié))存儲(chǔ)空間,那么它的表示范圍已經(jīng)確定,所以INT(1)和INT(20)對(duì)于存儲(chǔ)和計(jì)算是相同的。
5-?TIMESTAMP使用4個(gè)字節(jié)存儲(chǔ)空間,DATETIME使用8個(gè)字節(jié)存儲(chǔ)空間。所以TIMESTAMP只能表示1970 - 2038年,比DATETIME表示的范圍小得多,而且TIMESTAMP的值因時(shí)區(qū)不同而不同,可以根據(jù)需求來(lái)衡量?jī)蓚€(gè)類型的利弊。
6-?MySQL如下表達(dá)式不會(huì)使用索引:
select * from where id + 1 = 5
雖然我們很容易看出來(lái)id+1=5等價(jià)于id=4,但是MySQL無(wú)法自動(dòng)解析這個(gè)表達(dá)式,使用函數(shù)是同樣的道理。
選取適用的字段屬性
一般說(shuō)來(lái),數(shù)據(jù)庫(kù)中的表越小,在它上面執(zhí)行的查詢也就會(huì)越快。因此,在創(chuàng)建表的時(shí)候,為了獲得更好的性能,我們可以將表中字段的寬度設(shè)得盡可能小。當(dāng)然這對(duì)于INT這類型字段屬性來(lái)講就畫蛇添足了。
例如,在定義郵政編碼這個(gè)字段時(shí),如果將其設(shè)置為CHAR(255),顯然給數(shù)據(jù)庫(kù)增加了不必要的空間,甚至使用VARCHAR這種類型也是多余的,因?yàn)?code style="color:rgb(255,53,2);font-family:'Operator Mono', Consolas, Monaco, Menlo, monospace;font-size:14.4px;">CHAR(6)就可以很好的完成任務(wù)了。
盡量使用連接(JOIN)來(lái)代替子查詢
連接(JOIN)之所以更有效率一些,是因?yàn)镸ySQL不需要在內(nèi)存中創(chuàng)建臨時(shí)表來(lái)完成這個(gè)邏輯上的需要兩個(gè)步驟的查詢工作。
LIKE語(yǔ)句操作
一般情況下不鼓勵(lì)使用like操作,如果非使用不可,如何使用也是一個(gè)問題。like "%aaa%"?不會(huì)使用索引而like "aaa%"可以使用索引。
優(yōu)化LIMIT分頁(yè)
當(dāng)需要分頁(yè)操作時(shí),通常會(huì)使用LIMIT加上偏移量的辦法實(shí)現(xiàn),同時(shí)加上合適的ORDER BY字句。如果有對(duì)應(yīng)的索引,通常效率會(huì)不錯(cuò),否則,MySQL需要做大量的文件排序操作。
一個(gè)常見的問題是當(dāng)偏移量非常大的時(shí)候,比如:LIMIT 10000,20這樣的查詢,MySQL需要查詢10020條記錄然后只返回20條記錄,前面的10000條都將被拋棄,這樣的代價(jià)非常高。
優(yōu)化這種查詢一個(gè)最簡(jiǎn)單的辦法就是盡可能的使用覆蓋索引掃描,而不是查詢所有的列。然后根據(jù)需要做一次關(guān)聯(lián)查詢?cè)俜祷厮械牧小?duì)于偏移量很大時(shí),這樣做的效率會(huì)提升非常大。考慮下面的查詢:?SELECT a,b FROM film ORDER BY title LIMIT 50,5;
