索引就是帮助MySQL高效获取数据的数据结构(有序),在数据库管理系统中,除了数据之外,系统还维护着一些满足特定查找算法的数据结构,这些数据结构以某种方式引用数据,可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。
优点:
1、提高数据库的检索效率,降低数据库的io成本
2、通过索引对数据库进行排序,降低数据的排序成本,降低CPU的消耗
缺点:
1、建立索引需要占用空间
2、索引大大提高了数据的查询效率,同时也降低了数据的更新效率。如对表进行增删
改时效率降低。
MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的结构。
最常见的索引为B+Tree索引。大部分引擎都支持B+Tree索引。也是InnoDB的索引。
Hash索引,底层数据结构是通过哈希表实现的,只支持精确查询,不支持范围查询。
主键索引(primary):针对表中主键创建的所以索引,默认自动创建,只能有一个
唯一索引(unique):当某一列值不存在重复时,可以有多个
常规索引:快速定位数据的索引,可以有多个
全文索引(fulltext):全文索引查找文本中的关键词,可以有多个
在InnoDB中根据索引的存储形式可以分为以下两种:
聚集索引:将数据存储与索引放到一起,索引结构的叶子节点保存了整行数据。必须有,而且仅有
一个,对应主键索引。
二级索引:将数据与索引分开存储,索引的叶子节点仅保存了对应行数据的主键。可以存在多个。
聚集索引的选取原则:
1、如果存在主键索引,主键索引即是聚集索引
2、不存在主键索引,则选取第一个唯一索引作为聚集索引
3、都不存在,那么InnoDB将自动生成一个rowid作为隐藏的聚集索引
注意:通过二级索引查询整行数据时,先通过相应字段的二级索引查询到相应的主键,在通过聚集索引查询到对应的行数据。需要回表查询。
1、创建索引
create index 索引名 on 表名(字段名);
2、查看索引
show index from 表名;
3、删除索引
drop index 索引名 on 表名;
例:
1、为name创建索引
show index from tb_user;
2、为phone创建唯一索引
create unique index unique_user_phone on tb_user(phone);
3、为profession,age,status创建联合索引
create index ind_user_pro_age_sta on tb_user(profession,age,status);
4、为email创建合适的索引
create index ind_user_emal on tb_user(email);
在执行select之前加上explain,会获取MySQL如何执行select语句,包括表的连接和连接顺序。desc的效果相同。
如果索引是联合索引,那么就要遵循最左前缀法则。最左前缀法则是指,索引的最左列必须存在,且不跳过中间的列。
如果跳过列那么,后面的索引将会失效。
如果使用了范围查询,尽量使用<=,>=避免使用<>。否则会导致范围查询右侧的列失效
1、在索引上进行运算
2、字符串不加引号存在隐式类型转换
3、模糊匹配,尾部模糊走索引,头部模糊索引失效
4、使用or关键字时,两边都要有索引,否则索引失效
5、当MySQL评估索引比全表扫描更慢
在SQL语句中加入一些人为的提示来达到优化操作的目的,如以下索引的使用
1、use index
建议使用索引
explain select * from tb_user use index (inx_user_pro) where profession = '软件工程';
2、ignore index
不使用某个索引
explain select * from tb_user ignore index (inx_user_pro) where profession = '软件工程';
3、force index
必须使用索引
explain select * from tb_user force index (inx_user_pro) where profession = '软件工程';
在开发中尽量使用覆盖索引,避免使用select * ,即是需要查找的列在该索引中已经全部找到。
使用索引查询到一个或几个列后,并不能得到需要查找的全部的列,因此需要根据主键索引进行回表查询。
前缀索引:
当字段类型为text或者varchar时,当字符串很大时,需要很长的索引,查询是浪费大量的磁盘IO,影响效率。因此在构建索引时,只需要将字符串的前缀取出构建,节省空间。
只包含一列的索引
7.3.2 联合索引
包含多个列的索引