1. 程式人生 > >Mysql資料庫效能優化之查詢效能優化

Mysql資料庫效能優化之查詢效能優化

一、前言:為啥查詢速度會變慢?
通常來說,查詢的生命週期大致分為從客戶端、到伺服器,然後在伺服器上進行解析,生成執行計劃,執行,並返回結果給客戶端。其中執行可以說是最重要的階段,這其中包括了大量為了檢索資料到儲存引擎的呼叫以及呼叫後的資料處理,包括排序和分組等。在每一個消耗大量時間的查詢案例中,我們都能看到一些不必要的操作、某些操作被額外重複執行了很多次、某些操作執行的太慢。優化查詢的目的就是減少和消除這些操作所花費的時間。
二、優化資料訪問
可以通過兩個步驟分析低效的查詢
1、確認應用程式是否檢索大量超過需要的資料。這通常意味著訪問了太多的行,但有時候也可能是訪問了太多的列。
2、確認Mysql伺服器層是否在分析大量超過需要的資料行。
2.1是否向資料庫請求了不需要的資料


- 只查詢需要的記錄
mysql會查詢全部的結果集,客戶端的應用程式會接受全部的結果集資料,然後拋棄大部分資料。最簡單的做法就是在查詢後面加上limit;
- 避免在多表關聯時返回全部列
在編寫關聯查詢是隻返回你需要的列
- 不要總是取出全部列
當使用select * 是要保持懷疑的眼光。這會為伺服器帶來額外的I/O、記憶體和CPU的消耗。
- 避免重複查詢形同的資料
如果不小心會執行相同的查詢,比如在使用者評論時需要查詢使用者頭像的URL,那麼使用者多次評論的時候,反覆查詢這個資料。比較好的方案是,當初查詢的時候將這個資料快取起來,需要的時候從快取中取出,這樣效能會更好。
2.2MySql是否在掃描額外的記錄

最簡單的衡量查詢開銷的三個指標為:響應時間、掃描的行數、返回的行數;這三個指標都會記錄到Mysql的慢查詢日誌中,所以檢查慢日誌記錄是找出掃描行數過多的查詢的好辦法。
- 響應時間
響應時間是服務時間和排隊時間之和。服務時間是資料庫處理這個查詢真正花了多長時間。排隊時間是指伺服器因為等待某些資源而沒有真正執行查詢的時間——可以是I/O操作,可能是等待行鎖。
- 掃描的行數和返回的行數
。這在一定程度上能夠說明該查詢找到需要的資料的效率高不高,理想情況下、掃描的行數和返回的行數應該是相同的。
- 掃描的行數和訪問型別
在評估查詢開銷的時候,需要考慮一下從表中找到某一行資料的成本。
在explain語句中的type列反應了訪問型別。索引讓mysql以最高效、掃描行數最少的方式找到需要的記錄。讓我們來看看一個案例
select * from film_actor where film_id = 1;

這個查詢返回10行資料,通過explain的結果可以看到。mysql在索引idx_fk_film_id上使用了ref訪問型別來執行查詢:

msyql>explain select * from film_actor where film_id = 1
id:1
type:ref
key:idx_fk_film_id
key_len:2
rows:10
extra:

explain的結果顯示需要訪問10行資料。查詢優化器認為這中訪問型別可以高效的完成查詢。當我們刪除對應的所有執行這個查詢:

mysql> alter table film_actor drop foreign key fk_film_actor_film;
mysql>alter table film_actor drop key idx_fk_film_id;
mysql>explain select * from film_actor where film_id = 1
id:1
type:all
key:null
key_len:null
extra:using where
rows:5073

此時訪問型別變成了一個全表掃描(all),現在Mysql需要通過掃描5073條記錄來完成這個查詢。這裡的using where 表示msyql需要通過where條件來篩選儲存引擎返回的記錄

一般Mysql能夠通過使用如下三種方式應用where條件。從好到壞依次為:

  • 在索引中通過使用where條件來過濾不匹配的記錄。這是在儲存引擎層完成的。
  • 使用索引覆蓋掃描(在extra列出現了using index)來返回記錄,直接從索引中過濾不需要的記錄並返回命中的記錄。
  • 從資料表中返回資料,然後過濾不滿足條件的記錄(在extra列中出現using where)。在mysql服務層完成。mysql需要先從資料表讀出記錄然後過濾。
    如果發現查詢需要掃描大量的資料但只返回少數的行,那麼通常可以嘗試下面的技巧去優化它:
    • 使用索引覆蓋掃描,把所有需要用到的列都放到索引中,這樣儲存引擎無需回表獲取對應行就可以返回結果了
    • 改變庫表結構。
    • 重寫這個複雜的查詢,讓mysql優化器能夠以更優化的方式執行這個查詢。
      201頁