一、索引概述
- 索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引
- 优缺点
优点 缺点 提高数据检索的效率,降低数据库的io成本 索引列也是要占用空间的 通过索引列对数据进行排序,降低数据排序的成本,降低cpu的消耗 索引大大提高了查询效率,同时却也降低更新表的速度,如对表进行增删改效率降低
二、索引结构
MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的结构,主要包含一下几种:
索引结构 | 描述 |
B+Tree索引 | 最差常见的索引类型,大部分引擎都支持B+树索引 |
Hash索引 | 底层数据结构是用哈希表实现的,只有精确匹配索引列的查询才有效,不支持范围查询 |
R—tree (空间索引) | 空间索引是MyISAM引擎的一个特殊索引类型,主要用于地理空间数据类型,通常使用较少 |
Full-text (全文索引) | 是一种建立倒排索引,快速匹配文档的方式 |
三、索引分类
分类 | 含义 | 特点 | 关键字 |
主键索引 | 针对于表中主键创建的索引 | 默认自动创建 | primary |
唯一索引 | 避免同一个表中某数据列中的值重复 | 可以有多个 | unique |
常规索引 | 快速定位特定数据 | 可以有多个 | |
全文索引 | 查找文本中的关键字,而不是比较索引中的值 | 可以有多个 | fulltext |
在innoDB存储引擎中,根据索引的存储形式,可以分为以下两种
分类 | 含义 | 特点 |
聚集索引 (Clustered Index) | 将数据存储与索引放到一块,索引结构的叶子节点保存了行数据 | 必须有,而且只有一个 |
二级索引 (Secondary Index) | 将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键 | 可以存在多个 |
聚集索引选取规则:
1)如果存在主键,主键索引就是聚集索引
2)如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引
3)如果表没有主键,或没有合适的唯一索引,则innoDb会自动生成一个rowid作为隐藏的聚集索引
四、索引语法
- 创建索引
create [unique | fulltext] index 索引名 on 表名(index_col_name,...); - 查看索引
show index from 表名; - 删除索引
drop index 索引名 on 表名;
五、索引使用
- 最左前缀法则
如果索引了多列(联合索引),要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列。如果跳跃某一列,后面的字段索引失效。 - 范围查询
联合索引中,出现范围查询(>,<),范围查询右侧的列索引失效 - 索引列运算
不要在索引列上进行运算操作,否则索引将失效 - 字符串不加引号
字符串类型字段使用时,不加引号,索引将失效 - 模糊查询
如果仅仅是查询内容尾部模糊匹配,索引不会失效。如果是查询内容头部模糊匹配,索引失效 - or连接的条件
用or分隔开的条件,如果有一端没有索引,那么涉及的索引都不会被用到 - 数据分布影响
如果MySQL评估使用索引比全表更慢,则不会使用索引 - SQL提示
是优化数据库的一个重要手段,简单来说,就是在SQL语句中加入一些人为的提示来达到优化操作的目的
use index 告诉数据库,使用哪个索引
例如:explain select * from 表名 use index(索引名) where 查询条件;
ingnore index 告诉数据库,不要用哪个索引
例如:explain select * from 表名 ingnore index(索引名) where 查询条件;
force index 告诉数据库,必须走这个索引
例如:explain select * from 表名 force index(索引名) where 查询条件; - 覆盖索引
尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到),减少select * - 前缀索引
在长字符串或大文本字段时,可以将字符串的一部分前缀建立索引,这样可以大大节约索引空间,从而提高索引效率
create index 索引名称 on 表名(字段名(前n个字符));
六、索引设计原则
- 针对数据量比较大,且查询比较频繁的表建立索引
- 针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引
- 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。
- 如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引。
- 尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率。
- 要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率。
- 如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束它。当优化器知道每列是否包含NULL值时,它可以更好地确定哪个索引最有效地用于查询。