先分析一下查詢慢的原因:
- 網(wǎng)絡(luò)
- IO
- CPU
- 上下文調(diào)用
- 系統(tǒng)調(diào)用
- 生成統(tǒng)計(jì)信息
- 鎖等待
以上問題都是sql 查詢中 出現(xiàn)慢的原因西傀。
優(yōu)化數(shù)據(jù)訪問
- 查詢效率低下的主要問題是訪問的數(shù)據(jù)太多斤寇。某些查詢不可避免的篩選了大量的數(shù)據(jù),我們可以減少訪問數(shù)量進(jìn)行優(yōu)化
1.確認(rèn)應(yīng)用程序是否在檢索大量超過需要的數(shù)據(jù)
2.確認(rèn)mysql是否在檢索超過需要的數(shù)據(jù)行 - 是否向數(shù)據(jù)庫查詢了不需要的數(shù)據(jù)
1.查詢不需要的數(shù)據(jù)
2.多表關(guān)聯(lián)時(shí)返回了不需要的列
3.總是取出全部列
4.總是重復(fù)的查詢相同的數(shù)據(jù)
執(zhí)行過程的優(yōu)化
- 查詢緩存
在解析一個(gè)查詢之前拥褂,如果查詢緩存是打開的娘锁。如果命中了這個(gè)查詢,查詢會(huì)先檢驗(yàn)一下用戶權(quán)限饺鹃,如果用戶權(quán)限沒有問題致盟,會(huì)直接返回給客戶端,并跳過所有檢驗(yàn)過程 - 查詢優(yōu)化處理
1.語法解析和預(yù)處理
2.查詢優(yōu)化器
很多情況下mysql 會(huì) 選擇錯(cuò)誤的執(zhí)行計(jì)劃尤慰,原因如下:
1.信息統(tǒng)計(jì)不準(zhǔn)確
2.執(zhí)行計(jì)劃的成本不等同于執(zhí)行計(jì)劃的成本
3.mysql 的最優(yōu)和你想象得不一樣
4.mysql 不考慮并發(fā)情況
5.mysql 不受其控制得操作成本
優(yōu)化器的優(yōu)化策略
1.靜態(tài)優(yōu)化
直接對(duì)解析進(jìn)行優(yōu)化馏锡,并完成優(yōu)化
2.動(dòng)態(tài)優(yōu)化
與查詢的上下文有關(guān),也可能和取值伟端,索引對(duì)應(yīng)的行數(shù)有關(guān)
靜態(tài)優(yōu)化只需要一次杯道。
動(dòng)態(tài)優(yōu)化需要每次查詢重新評(píng)估
優(yōu)化器的優(yōu)化類型:
重新定義關(guān)聯(lián)表的順序
將外連接轉(zhuǎn)化成內(nèi)連接,內(nèi)連接效率高于外連接
優(yōu)化 count().max().min()
覆蓋所有
子查詢優(yōu)化
等值傳播
優(yōu)化特定類型的查詢
- 優(yōu)化count查詢
myisam 的 count 是用一個(gè)變量來存儲(chǔ)的,沒有任何條件的count() 效率高 直接返回党巾。
- 優(yōu)化關(guān)聯(lián)查詢
確保 on 和 using 的子查詢上有索引萎庭,在創(chuàng)建的時(shí)候要考慮到關(guān)聯(lián)順序
確保任何 order by 和 group by 只涉及到一張表中的列,這樣 mysql 才可以優(yōu)化這個(gè)過程
- 優(yōu)化子查詢
子查詢建議盡量使用 關(guān)聯(lián)查詢代替
- 優(yōu)化limit 分頁
盡量使用索引覆蓋齿拂,而不是查詢所有的列
例:
select film_id,description from film order by title limit 50,5
explain select film.film_id,film.description from film inner join (select film_id from film order by title limit 50,5) as lim using(film_id);
- 優(yōu)化 union 查詢
除非確實(shí)需要服務(wù)器消除重復(fù)行驳规,否則使用 union all。
union 在查詢的時(shí)候 會(huì) 在臨時(shí)表 加上 distinct 署海,代價(jià)比較高