MySQL常用優(yōu)化

SQL優(yōu)化

1.字段加索引。這個(gè)是大家都能想到的,但不得不說(shuō),加索引也是有技巧的,對(duì)于一些區(qū)分不是很大的情況來(lái)說(shuō),例如一個(gè)字段表示刪除與否的狀態(tài)只有0,1兩種值的情況下,這個(gè)字段就不要加索引了。意義不大。同時(shí),如果某張表里有排序字段的話,而且出現(xiàn)的頻率比較高的,例如通過(guò)符合索引來(lái)加字段。例如(field_name,create_time),經(jīng)常需要這樣查詢where field = field_name order create_time。當(dāng)然,復(fù)合索引也遵循前綴的原則,當(dāng)我們只是需要where field = field_name的時(shí)候,查詢也會(huì)走索引。

2.使用IN查詢時(shí)里面的值不應(yīng)該過(guò)多。MySQL對(duì)于IN做了相應(yīng)的優(yōu)化,即將IN中的常量全部存儲(chǔ)在一個(gè)數(shù)組里面,而且這個(gè)數(shù)組是排好序的。但是如果數(shù)值較多,產(chǎn)生的消耗也是比較大的。再例如:select id from t where num in(1,2,3) 對(duì)于連續(xù)的數(shù)值,能用 between 就不要用 in 。

3.在查詢的過(guò)程中如果不需要查詢出全部字段,盡量不要使用select 查詢。MySQL在查詢數(shù)據(jù)的時(shí)候,需要先把數(shù)據(jù)先拿出來(lái)然后再按照條件來(lái)篩選的。如果用查詢的話,就需要把整條記錄都拿出,增加了很多不必要的消耗(cpu、io、內(nèi)存、網(wǎng)絡(luò)帶寬);增加了使用覆蓋索引的可能性。

4.當(dāng)需要拿出一條數(shù)據(jù)時(shí),在sql結(jié)尾處最好加上limit 1。

5.模糊查詢的時(shí)候進(jìn)行用右模糊的方式。例如select field_name from table_name like field_name like 'xxx%'。這樣做的好處就是在查詢的時(shí)候會(huì)走索引,減少查詢時(shí)間。

6.連表查詢的時(shí)候盡量使用inner join,避免left join;被驅(qū)動(dòng)表的索引字段作為on的限制字段以此合理利用索引。參與聯(lián)合查詢的表至少為2張表,一般都存在大小之分。如果連接方式是inner join,在沒(méi)有其他過(guò)濾條件的情況下MySQL會(huì)自動(dòng)選擇小表作為驅(qū)動(dòng)表,但是left join在驅(qū)動(dòng)表的選擇上遵循的是左邊驅(qū)動(dòng)右邊的原則,即left join左邊的表名為驅(qū)動(dòng)表。

7.查詢的判斷條件中盡量的不要使用!=,not in或者是判斷null等情況。這些情況會(huì)導(dǎo)致查詢的效率變慢。

8.合理的利用分頁(yè)方式來(lái)提高分頁(yè)效率。例如select id,name from product limit 800000, 20。這條sql語(yǔ)句在隨著表的增大的過(guò)程中查詢會(huì)變得越來(lái)越慢。這種情況我們可以取前一頁(yè)的最大行數(shù)的id,然后根據(jù)這個(gè)最大的id來(lái)限制下一頁(yè)的起點(diǎn)。例如select id,name from product where id > 800000 limit 20。

9.如果限制條件中其他字段沒(méi)有索引,盡量少用or。or條件中如果有其他字段沒(méi)有索引的話,容易使得mysql在查詢的時(shí)候不走索引。大多時(shí)候都是用union all來(lái)代替or。

10.where字句中避免對(duì)字段進(jìn)行表達(dá)式操作。例如select user_name from user where age*2=30。對(duì)字段進(jìn)行算數(shù)操作會(huì)使其不走索引,所以這種情況應(yīng)該改成select user_name from user where age=15。

11.必要是強(qiáng)制使用force index讓查詢走索引。有時(shí)候MySQL的優(yōu)化器會(huì)走它認(rèn)為的合理的索引,但那時(shí)候可能不是我們想要的,所以有時(shí)候要使用強(qiáng)制所以的命令。

12.連表時(shí)盡量使用inner join。參與聯(lián)合查詢的表至少為2張表,一般都存在大小之分。如果連接方式是inner join,在沒(méi)有其他過(guò)濾條件的情況下MySQL會(huì)自動(dòng)選擇小表作為驅(qū)動(dòng)表。

SQL檢驗(yàn)

1.使用Explain來(lái)查看自己的sql語(yǔ)句使用索引的情況。如果是在命令行模式下的話,則是explain select.........的形式來(lái)查看。如果是用的Navicat這樣的sql工具的話,也可以在查詢的時(shí)候直接按解釋,也會(huì)出現(xiàn)sql索引使用的情況。形如下面:

MySQL常用優(yōu)化

其主要關(guān)鍵的幾個(gè)字段的意思如下:

1. type列,連接類型。一個(gè)好的sql語(yǔ)句至少要達(dá)到range級(jí)別。杜絕出現(xiàn)all級(jí)別

2. key列,使用到的索引名。如果沒(méi)有選擇索引,值是NULL??梢圆扇?qiáng)制索引方式

3. key_len列,索引長(zhǎng)度

4. rows列,掃描行數(shù)。該值是個(gè)預(yù)估值

5. extra列,詳細(xì)說(shuō)明。注意常見(jiàn)的不太友好的值有:Using filesort, Using temporary

當(dāng)然的,mysql還有其他方面的優(yōu)化。如果你真的想要深入對(duì)mysql的理解的話,也可以買(mǎi)一些書(shū)籍來(lái)看,深入mysql才能真正知道如何優(yōu)化最好。

2.通過(guò)慢查詢?nèi)罩緛?lái)定位查詢時(shí)間久的sql語(yǔ)句。執(zhí)行以下命令時(shí),可以查詢當(dāng)前的慢查詢的設(shè)置時(shí)間,默認(rèn)是10s。

show variables like 'long_query_time'

修改慢查詢時(shí)間,以下命令是設(shè)置慢查詢時(shí)間為2s。

set long_query_time=2

然后我們?cè)试Ssql語(yǔ)句,如果sql語(yǔ)句時(shí)間超過(guò)2s的話,就會(huì)被記錄。相應(yīng)的,記錄的位置我們可以參考MySQL的my.ini文件里的datadir這個(gè)參數(shù)的目錄,進(jìn)去相應(yīng)的目錄之后,我們可以看到一個(gè)slow.log結(jié)尾的文件,里面記錄的就是我們運(yùn)行的超過(guò)2s的mysql的查詢記錄。

?著作權(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),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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