正兒八經(jīng)mysql優(yōu)化!
mysql數(shù)據(jù)量少,優(yōu)化沒必要,數(shù)據(jù)量大,優(yōu)化少不了,不優(yōu)化一個查詢10秒,優(yōu)化得當(dāng),同樣查詢10毫秒。
這是多么痛的領(lǐng)悟!
mysql優(yōu)化,說程序員的話就是:索引優(yōu)化和where條件優(yōu)化。
實驗環(huán)境:MacBook Pro MJLQ2CH/A,mysql5.7,數(shù)據(jù)量:212萬+
ONE:
| select * from article INNER JOIN ( SELECT id FROM article WHERE length(content_url) > 0 and (select status from source where id = article.source_id)=1 and (select status from category where id = article.category_id)=1 and status = 1 and id < 2164931 order by stick desc,pub_time desc limit 240,15 ) AS tUSING(id); |
咋一看,大佬肯定會想殺了我,沒事做啥自關(guān)聯(lián),還是inner join。XX樓的,把我的殺豬刀拿來,我要宰了博主!!!
說實話,早上出門我的腦袋沒被門擠,我也不想這樣的。
1.數(shù)據(jù)量大了,你要做offset很大的分頁查詢,還真的這樣提速,原因 ---> 用join子表中的id覆蓋到全表,避免全表掃描。
看我的order by(細(xì)語:不就是個order by,TM誰不會寫),你把這個order by換成你自己的表中的字段desc or explain看看。Extra ---> filesort ! shit !
2.針對這種多個條件的order by,通常我們會直接給兩個字段分別加index,然而還是會Extra ---> filesort。另辟蹊徑,給order by后面的所有條件加一個聯(lián)合索引,注意順序一定要和你的order by順序一致。這樣Extra就只剩下where了。
再看看where,(select status from source where id = article.source_id)=1 and ...又啥JB寫法!
3.想過用join+index的方式,最后測試出來,和這種方式幾乎無差別。生產(chǎn)環(huán)境是這樣寫的,那就這樣吧,還能少兩個索引(source_id,category_id),懶病犯了誰都阻擋不了,以后吃虧了又回來繼續(xù)優(yōu)化唄。
4.這個點是我昨晚才get到的,where條件的滿足順序是優(yōu)先滿足最后一個條件,從右到左,經(jīng)過刪除index測試,確實有效果,能從6秒降到4秒,優(yōu)化了index之后再次測試發(fā)現(xiàn)順序?qū)臅r影響幾乎可以忽略不計,0.X毫秒。
TWO:
| select * from article INNER JOIN ( SELECT id FROM article WHERE INSTR(ifnull(title,''),'戰(zhàn)狼') > 0 and status != 9 order by pub_time desc limit 100,10 ) AS t USING(id); |
嗯——又是inner join.......
| INSTR(ifnull(title,''),'戰(zhàn)狼') > 0,為啥不用like...... |
1.考慮到這是管理平臺的搜索,沒有去搜索引擎上搜,搜索引擎是一個小時才同步一次數(shù)據(jù),數(shù)據(jù)不全。管理人員搜索時只管他要的結(jié)果,like %XX%不能走索引,效率比instr低了5倍,又測試了regexp '.*XX*.',還是比instr耗時多一點,索性.....
| desc or explain看看,filesort.....給pub_time加個index看看,還是filesort..... |