MySQL索引那些要知道的事
假如我们没有添加索引,那么在查询时就会触发全表扫描,效率就会比较低。但是即便建立了索引,使用不当也可能导致索引失效。
1.避免使用 or 查询,可以使用 union 或者子查询来替代
早期的 MySQL 版本使用 or 查询可能会导致索引失效,在 MySQL 5.0 之后的版本中引入了索引合并,简单来说就是把多条件查询,比如 or 或 and 查询的结果集进行合并交集或并集的功能,因此就不会导致索引失效的问题了。
2.避免在 where 查询条件中使用 != 或者 <> 操作符,会导致放弃索引而进行全表扫描。
可以使用union代替
3.避免在列上进行运算操作
不要在列字段上进行算术运算或其他表达式运算,否则可能会导致查询引擎无法正确使用索引,从而影响了查询的效率。
4.正确使用联合索引
MySQL InnoDB 引擎使用 B+ 树来建立索引,在每次查询复合字段时是从左往右匹配数据的,即最左匹配原则,因此在创建联合索引的时候需要注意索引创建的顺序。例如,我们创建了一个联合索引是index(name,age,sex),那么当我们使用name、name+age、name+age+sex等这种最左前缀查询条件时,就会触发联合索引进行查询;然而如果非最左匹配的查询条件,例如,sex+name这种查询条件就不会触发联合索引。
当然,当我们已经有了(name,age)这个联合索引之后,一般情况下就不需要在 为name 字段单独创建索引了,这样就可以少维护一个索引。
使用explain查看sql执行计划
比如:
select_type:表示SELECT的类型,常见的取值有:
-
SIMPLE 简单表,不使用表连接或子查询
-
PRIMARY 主查询,即外层的查询
-
UNION UNION中的第二个或者后面的查询语句
-
SUBQUERY 子查询中的第一个
table:输出结果集的表(表别名)
type:表示MySQL在表中找到所需行的方式,或者叫访问类型。常见访问类型如下,从上到下,性能由差到最好:
-
ALL 全表扫描,MySQL遍历全表来找到匹配行,一般是没有where条件或者where条件没有使用索引的查询语句
-
index 索引全扫描,MySQL遍历整个索引来查询匹配行,并不会扫描表,一般是查询的字段都有索引的查询语句
-
range 索引范围扫描,常用于<、<=、>、>=、between等操作
-
ref 使用非唯一索引查找数据
-
eq_ref 唯一索引扫描
-
const,system 单表最多有一个匹配行
-
NULL 不用扫描表或索引
possible_keys: 表示查询可能使用的索引
key: 实际使用的索引
key_len: 使用索引字段的长度
ref: 列与索引的比较
rows: 大概扫描的行数
filtered: 按表条件过滤的行百分比。
Extra: 执行情况的说明和描述,包含不适合在其他列中显示但是对执行计划非常重要的额外信息