什么是索引
索引是存储引擎用于快速找到记录的一种数据结构。
索引操作语句
# 1. 增加索引
alter table 表名 add index 索引名(列名)
# 2. 删除索引
drop index 索引名 on 表名
# 3. 查看当前表的索引
show index from 表名
例子
CREATE TABLE `edu_user` (
`id` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8_general_ci NOT NULL,
`username` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
`password` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8_general_ci NOT NULL COMMENT '密码',
`role_id` int NOT NULL COMMENT '账号角色id',
`role_name` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8_general_ci DEFAULT NULL COMMENT '账号角色名称',
`role_info_id` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8_general_ci DEFAULT NULL COMMENT '角色具体信息id',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 ROW_FORMAT=COMPACT COMMENT='账号信息表';
未使用索引查询:
使用索引查询:
扫描行数为1行,而且使用ref索引。不需要扫描全表,主要还是因为索引是有序的。
mysql四种索引类型
-
FULLTEXT
利用查询关键字和查询列内容之间的相关度进行检索,可以利用全文索引来提高匹配的速度。 -
NORMAL
普通索引,提高查询速度。 -
SPATIAL
用于索引多维数据。 -
UNIQUE
唯一值索引。
mysql索引方法
-
BTREE
被索引的列都是排过序的
适合范围查找
支持order by语句 -
HASH
仅支持"=","IN"和"<=>"精确查询,不能使用范围查询
不支持排序
在任何时候都不能避免表扫描
检索效率高,索引的检索可以一次定位
索引应用种类
聚簇索引、覆盖索引、辅助索引、前缀索引、联合索引、哈希索引
聚簇索引(主键索引)
首先聚簇索引不是一种存储类型,而是一种数据存储方式,每张表只能有一个聚簇索引。
具体存储方式:
按照每张表的主键构造一棵B+树,叶子节点页存放整张表的行数据(所以叶子节点页可以叫数据页),节点页只包含索引列(一般通过主键聚集数据)。在InnoDB引擎中,索引组织表中数据按照主键顺序存放。所以聚簇索引在InnoDB中,索引组织表中的数据也是索引的一部分。
利用聚簇索引排序查找:
如果定义了主键,InnoDB会自动使用主键来创建聚集索引。
如果没有定义主键,InnoDB会选择一个唯一的非空索引代替主键。
如果没有唯一的非空索引,InnoDB会隐式定义一个主键来作为聚集索引。
辅助索引(非聚簇索引)
辅助索引,叶子节点不包含行记录的全部数。叶子节点除了包含键值外,每个叶子节点中索引行还包含一个书签,该书签就是行数据的聚簇索引键(图中主键的地址)。
查找思路:
先根据指定的字段条件排序,然后找到叶子节点上面的数据指针,找到对应的主键索引,再回表找到该主键索引对应的数据记录。
利用辅助索引查找:
覆盖索引(不需要回表)
InnoDB引擎支持覆盖索引,即从辅助索引中就可以得到查询的记录,而不需要查询聚集索引中的记录,减少IO操作次数,所以覆盖索引对于Innodb存储引擎将会特别有效。
通过辅助索引username_idx统计记录数,而不是回表到聚簇索引表统计。
联合索引
单个索引,就是在一个列上建立一个索引,而联合索引就是多个列建立一个索引。
联合索引内部结构:
可以看到联合索引是按照从左到右顺序进行排序的,所以对于(a,b)先比较a再比较b。
联合索引使用最左匹配原则:
结论:如果只使用了后面的索引,那么不会走索引,会进行全表扫描。
例子:利用最左匹配原则可以减少行扫描:
联合索引结构(username,password):
如果没有联合索引,那么我们会先对password排序,扫描7行记录,然后再where条件查询username。
如果使用联合索引,那么我们会先where条件查询username,扫描1行记录,然后对这一行记录再排序。
索引设计注意点1:选择性高的列作为索引列
重复列太多还是会扫描很多的行。
索引设计注意点2:独立列作为索引列
独立列指的是索引列不能作为表达式的一部分,否则会造成索引失效,全表扫描。
索引设计注意点3:like前置模糊查询使索引失效
like的前置模糊查询会使索引失效。
like的后置模糊查询不会使索引失效。
索引设计注意点4:group by少混用未加索引的列
username使用了索引,password没有使用索引。使用了临时空间。
参考
《高性能mysql》
《MySQL技术内幕 InnoDB存储引擎》