MySQL数据库优化之索引
索引
1、索引概述
索引是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护者满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。
不建立索引,查询效率会很慢
2、索引优势劣势
2.1 优势
(1)类似于书籍的目录索引,提高数据检索的效率,降低数据库的IO成本
(2)通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗
2.2 劣势
(1)实际上索引也是一张表,该表中保存了主键与索引字段,并指向实体类的记录,所以索引列也是要占用空间的。
(2)虽然索引大大提高了查询效率,同时却也降低更新表的速度,如对表进行INSERT、UPDATE、DELETE、因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段,都会调整因为更新所带来的键值变化后的索引信息。
3、索引结构
索引是在MySQL的存储引擎层中实现的,而不是在服务器层实现的。所以每种存储引擎的索引都不一定完全相同,也不是所有的存储引擎都支持所有的索引类型的。
3.1 索引种类
MySQL目前提供了以下四种索引
(1)BTREE索引:最常见的索引类型,大部分索引都支持B树索引。
(2)HASH索引:只有Memory引擎支持,使用场景简单。
(3)R-tree索引(空间索引):空间索引是MyISAM引擎的一个特殊索引类型,主要用于地理空间数据类型,通常使用较少,不做特别介绍。
(4)Full-text(全文索引):全文索引也是MyISAM的一个特殊索引类型,主要用于全文索引,InnoDB从Mysql5.6版本开始支持全文索引。
3.2 存储引擎对索引类型的支持
索引 InnoDB引擎 MyISAM引擎 Memory引擎
BTREE索引 支持 支持 支持
HASH索引 不支持 不支持 支持
R-tree索引 不支持 支持 不支持
Full-text 5.6版本后支持 支持 不支持
平常索引指的是B+树(多路搜素树)结构组织的索引。其中聚集索引、复合索引、前缀索引、唯一索引默认都是使用B+tree树索引,统称为索引。
3.3 BTREE结构
BTree又叫多路平衡索引树
3.3.1 特性
对于一个m叉的BTree树
(1)树中每个节点最多包含m个孩子。
(2)除根节点与叶子节点外,每个节点至少有[ceil(m/2)]个孩子 (ceil: 向上取整)。
(3)若根节点不是叶子节点,则至少有两个孩子。
(4)所有的叶子节点都在同一层。
(5)每个非叶子节点由n个key与n+1个指针组成,其中[ceil(m/2)-1]<=n <=m-1
3.3.2 优点
BTREE树和二叉树相比,查询数据的效率更高,因为对于相同的数据量来说,BTREE的层级结构比二叉树小,因此搜索速度快。
3.4 B+TREE结构
B+Tree为BTree的变种,B+Tree与BTree的区别为:
(1)n叉B+Tree最多含有n个key,而BTree最多含有n-1个key。
(2)B+Tree的叶子节点保存所有的key信息,依key大小顺序排列。
(3)所有的非叶子节点都可以看作是key的索引部分。
3.4.1 优点
由于B+Tree只有叶子节点保存key信息,查询任何key都要从root走到叶子。所以B+Tree的查询效率更加稳定。
3.4.2 MySQL中的B+Tree
MySql索引数据结构对经典的B+Tree进行了优化。在原B+Tree的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+Tree,提高区间访问的性能。
4、索引分类
4.1 单值索引
一个索引只包含单个列,一个表可以有多个单列索引
4.2 唯一索引
索引列的值必须唯一,但允许有空值
4.3 复合索引
一个索引包含多个列
5、索引语法
5.1 创建索引
语法
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [USING index_type] ON tbl_name(index_col_name....)
index_col_name : column_name[(length)][ASC|DESC]
//例子一
create index idx_city_name on city(city_name);
5.2 查看索引
语法
show index from 对应表的名字;
或者
show index from 对应表的名字\G;
//例子二
show index from city;
5.3 删除索引
语法
DROP INDEX 对应索引的名字 on 对应表的名子;
//例子三
drop index idx_city_name on city;
5.4 ALTER命令
语法
//1.该语句添加一个主键,意味着索引值必须是唯一的,且不能为NULL
alter table 对应表的名字 add primary key (字段列表);
//2.该语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)
alter table 对应表的名字 add unique 对应索引的名字 (字段列表);
//3.添加普通索引,索引值可以出现多次
alter table 对应表的名字 add index 对应索引的名字 (字段列表);
//4.该语句指定了索引为FULLTEXT,用于全文索引
alter table 对应表的名字 add fulltext 对应索引的名字 (字段列表);
//例子三
alter table city add unique idx_city_name (city_name);
6、索引设计原则
(1)对查询频次较高,且数据量比较大的表建立索引。
(2)索引字段的选择,最佳候选列应当从where子句的条件中提取,如果where子句中的组合比较多,那么应当挑选最常用、过滤效果最好的列的组合。
(3)使用唯一索引,区分度越高,使用索引的效率越高。
(4)索引可以有效的提升查询数据的效率,但索引数量过多,维护代价也会很高,mysql的选择效率也会很高,效率降低。
(5)使用短索引,索引创建之后也是使用硬盘来存储的,因此提升索引访问的I/O效率,也可以提升总体的访问效率。假如构成索引的字段总长度比较短,那么在给定大小的存储块内可以存储更多的索引值,相应的可以有效的提升MySQL访问索引的I/O效率。
(6)利用最左前缀,N个列组合而成的组合索引,那么相当于是创建了N个索引,如果查询时where子句中使用了组成该索引的前几个字段,那么这条查询SQL可以利用组合索引来提升查询效率。
//创建复合索引
//该语句就相当于对name创建索引,对name,email创建了索引,对name,email,status也创建了索引
CREATE INDEX idx_name_email_status on tb_seller(NAME, email, STATUS);