索引是帮助高效获取数据的数据结构,如B+Tree
没有索引会导致全表扫描,数据量较大会造成性能问题
优势和劣势
- 优势
- 提高数据检索效率,降低数据库IO成本
- 通过索引对数据进行排序,降低数据排序成本,降低CPU消耗
- 劣势
- 索引其实也是一张表,保存主键与索引字段,并指向实体类的记录,所以索引也是需要占用空间的
- 提升了查询效率,但降低了更新表的速度(增、删、改),因为会导致索引的变化,所以并不是索引越多越好
索引结构
索引是在存储引擎中实现的,而不是在服务器层实现的,所以不同的存储引擎也不一定相同,也不是所有的存储引擎都支持所有的索引类型。MySQL中主要提供如下4种索引类型:
- BTREE索引:最常见的索引
- HASH索引:只有Memory引擎支持
- R-tree索引(空间索引):MylSAM引擎的一种特殊索引,主要应用于地理空间数据类型
- Full-text(全文索引):MylSAM引擎的一种特殊索引,主要用于全文检索,InnoDB从5.6版本才开始支持
聚集索引、复合索引、前缀索引、唯一索引默认都使用B+tree索引(多路搜索树),统称为索引
BTREE索引
- BTree又叫多路平衡搜索树,一棵m叉的BTree特性如下:
- 树种每个节点最多包含m个孩子
- 除根节点与叶子节点外,每个节点至少有【ceil(m/2)】个孩子
- 若根节点不是叶子节点,则至少有两个孩子
- 所有的叶子节点都在同一层
- 每个非叶子节点由n个key与n+1个指针组成,其中【ceil(m/2)-1】<= n <=m-1
BTree与二叉树相比,查询效率更高,因为对于相同数据量来说,BTree的层级结构比二叉树小,因此搜索速度较快
B+TREE结构
B+TREE是BTREE结构的变种,区别如下:
- n叉B+Tree最多含有n个key,而BTree最多含有n-1个key
- B+TREE的叶子节点保存所有key的信息,依照key大小顺序排列
- 所有的非叶子节点都可以看作是key的索引部分
因为只有叶子节点保存key信息,查询任何key都要从root走到叶子,所以B+Tree的查询效率更加稳定。
在MySQL中对经典的B+Tree进行了优化,增加一个指向相邻叶子节点的链表指针,形成了带有顺序指针的B+Tree,提高区间访问的性能。
索引的分类
单值索引:一个索引只包含一个列,一个表可以有多个单列索引
唯一索引:索引列的值必须唯一,但允许有空值
复合索引:一个索引包含多个列
索引语法
索引可以在创建表时增加,也可以随时增加新的索引
创建索引的语法:create index idx_user_name on sys_user(user_name)
查看索引:show index from sys_user
删除索引:drop index idx_user_name on sys_user
ALTER命令创建索引:
- alter table sys_user add primary key(user_name) 主键,唯一且不能为NULL
- alter table sys_user add unique idx_user_name(user_name) 唯一索引,可以为NULL
- alter table sys_user add index idx_user_name(user_name) 普通索引
- alter table sys_user add fulltext idx_user_name(user_name) 全文索引
索引设计原则
- 查询频率较高,且数据量较大的表建立索引
- where子句的条件中提取索引字段,挑选最常用、过滤效果最好的列;
- 使用唯一索引,区分度越高,使用索引的效率越高;
- 索引并不是越多越好,单表一般限制在5个以内,对于查询需求较大的表效益较高,对增、删、改操作会带来维护索引的成本;
- 使用短字段建索引,索引创建后是存储在硬盘中,因此提升索引访问的I/O效率,也可以提升总体的访问效率。若构成索引的字段总长度较短,在给定大小的存储块内就可以存储更多的索引值,相应的可以有效提升MySQL访问索引的I/O效率;
- 针对于复合索引,采用最左索引。N个列组合而成的复合索引,相当于创建了N个索引,查询时where子句中使用了组成该索引的前几个字段,那么就可以利用到这个复合索引带来的优势。例如:字段one、two、three三个字段创建组合索引create index idx_name on sys_user(one,two,three) 就相当于创建了one索引、one,two索引、one,two,three索引,即只要查询的时候包含第一个索引,那么就会走索引;