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的逻辑就会出问题。
注:索引优化和代码结构优化一样,都是一项长期的工作