mysql索引優化一直以來是DBA和開發人員長期堅持的一項基本工作,合理的索引對於業務來說非常重要,合理的索引能有效改善性能。因此在開發中,定期排查索引的有效性很重要,排查的根據就是歷史sql,排查的目的就是優化索引,一個合格的開發人員要考慮未來1年的數據量的情況下sql的執行效率。
索引是否有效的方法是explain,它能反應很多內容,具體的不再贅述看下面的sql示例。
訪問類型 ALL、index、range、 ref、eq_ref、const、system、NULL(從左到右,性能遞增)
mysql> explain select id,created,expire from ex_xxx force index(PRIMARY) where status = 1 and created > 1546272000 and id < 17149185 and master_id = 0 order by id desc limit 200\G
// 使用強制索引,在真實查詢耗時 200 rows in set (0.00 sec)
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: ex_material
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: NULL
rows: 1553584
Extra: Using where
1 row in set (0.00 sec)
//不使用強制索引,真實查詢耗時 200 rows in set (1.39 sec)
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: ex_material
type: ref
possible_keys: PRIMARY,idx_master_id,idx_masterid_dspid_filesource_isd,idx_created
key: idx_master_id
key_len: 4
ref: const
rows: 1553584
Extra: Using index condition; Using where
1 row in set (0.00 sec)
顯然mysql在查詢優化時,使用了type=ref的索引,然後當idx_master_id建立的不合理時(發現320w數據,master_id=0的有310w,區分度不高),就會出現速度ref 類型比 range慢的情況。
這裏就可以發現強制索引的用途了,可以使用force index 指定索引,來改善查詢性能。
不過建議是臨時sql查詢使用,因爲線上數據隨着量的增加,調整索引是很常見的事情,如果在某個時間刪除了,那麼使用force index的邏輯就會出問題。
注:索引優化和代碼結構優化一樣,都是一項長期的工作