索引介绍
相当于目录,能够提高查询性能。但因为其会再建一个空间来存放这些索引,所以会消耗部分空间,并且在对数据进行插入、更新等操作时,也会自动对索引目录进行修改,因此某些情况下也会降低性能
作用
通过设置关键字和数据位置的映射关系,从而加快检索,是较为常用的优化手段
关键字
从数据中心提取,用于标识、检索数据的特定内容
索引为什么快
- 索引相对于数据本身,数据量小
- 关键字都是排好序的,通过遍历也可以确定位置
索引类型
Mysql中的索引类型包括:普通索引、唯一索引、主键索引和全文索引,其中不同的索引类型仅仅是对关键字的限制不同,其他方面效果都是一样的
(1)普通索引
对索引关键字没限制
key/index(列名1,列名2, ...)
(2)唯一索引
要求记录提供的关键字不能重复
unique key(列名1,列名2, ...)
(3)主键索引
要求关键字不能重复,且不能为null
primary key(列名1,列名2, ...)
(4)全文索引
fulltext(列名1,列名2, ...)
需要引擎为myisam
才能使用该索引,该索引的列可以通过使用:match(列名) ... against('查询内容')
,来实现模糊查询,举例:
mysql> select * from peoples where match(username) against('john mike');
注:
全文索引在5.7.6之前的版本里不支持中文
设置索引
(1)建表时设置
直接在后面写:索引类型(列名),即可,举例:
CREATE TABLE people1 (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
username varchar(45) NOT NULL,
password char(32) not null comment '密码',
time datetime,
PRIMARY KEY (id),
unique(username),
key(password),
index(time)
);
(2)添加索引
当表已经建好时,要添加索引可以通过下面命令实现:
alter table 表名 add 索引类型(列名);
举例:
mysql> alter table peoples add fulltext(username);
删除索引
alter table drop primary key
# 直接删除主键索引
alter table drop key 索引名字
# 根据索引名字删除除主键类型以外的索引
注:
删除主键索引时,由于主键通常伴随着自动增长,即自增还依赖于主键。因此需要先去掉自增以后,再删除主键,命令如下:
alter table xxx modify id int, drop primary key;
不过一般是不需要删除主键的,对于主键的设计一定要与业务逻辑无关
查看索引
查看表中索引设置情况
通过命令:
desc 表名
可以查看某个表下的索引(在key列),还有下面命令也可以查看索引,并且更详细:
show index from 表名\G
执行计划查看索引使用情况
可以通过explain 语句
查看是否使用到索引(主要看possible_keys
查看可能用到的索引,以及key
查看真正选择使用的索引)
索引使用场景
常在含where
/order by
/join
的查询语句中使用到索引
联合索引
使用场景
对于查询时某些字段一般组合起来检索的情况,适合使用联合索引,例如下面的情况:
select * from xxx where name like "xxx%" and work like "yyy%";
此时name
和work
是成对出现的,那么设置联合索引(name, work)
就相比分别对name
和work
设置索引的效率更高
排序机制
对于多个字段的联合索引,其排序是先根据从左边第一个字段开始排序,如果字段相同,在比较右边的下一个字段
前缀索引
概念
默认索引都是使用字段的全部内容进行索引,但在一些情况下,我们可以仅需要使用到字段的前几个字符来建立索引,例如一些加密算法计算的字段,其前几位基本就可以保证数据的唯一性,此时就适合使用前缀索引。使用前缀能够用更少的空间更高效的建立索引,并且索引长度越小速度越快
前缀索引适合情况判断
想要判断某个字段是否适合使用前缀索引,可以通过left(字段, 截取长度)
函数判断某个字段前n位的重合度,例如下面命令:
select count(*) / count(distinct left(字段, n)) from yyy;
此时如果值越小(接近1),说明该字段的前n位的不重复度很高,就适合使用前缀索引,此时就可以通过下面命令给字段添加前n位的前缀索引:
alter table yyy add index(xxx(n));
索引结构
索引的结构主要有三种:B树、hash、聚簇索引
B树索引
最常用的索引结构(也是索引字段默认的结构),基于B树结构,对于=
/>
/<
/like
/between
等操作查询效率高
hash索引
即基于hash表方式存储的结构,此时所有的key基于hash计算唯一值,但由于hash值无法比对,因此无法使用范围查找(例如:... where name like "xxx%"
/ ... where age > 10
),只适合在精确查找的场景使用
聚簇索引
关键字和记录放在一起存储的结构(前两者索引都是关键字和数据位置的映射关系),用Json格式模拟表示的话,常规索引如下:
{
xxx: 0x789798
}
而聚簇索引则表示如下:
{
xxx: {
name: aaa,
pwd: bbb
}
}
在Mysql中,Innodb引擎下的主键就是采用聚簇索引的结构
索引使用注意
包含的逻辑不能用like,应该用全文索引
对于包含关系的查询逻辑,不要使用like
进行模糊查询效率极低,此时应该使用全文索引来完成,例如下面的语句就不应该出现:
select * from xxx where name like "%aaa%";
语法不规范导致索引没用的情况
- 字段没有独立出现在表达式的一侧,举例:
select * from xxx where id=2;
select * from xxx where id+1=2;
假如id设置了主键索引,那么第一句将会使用到索引,而第二句因为语法不规范,而不会使用到索引(可以通过explain
查看)
- like查询时以通配符开头,举例:
select * from xxx where name like 'xxx%';
select * from xxx where name like '%xxx';
假如name设置了索引,那么第一句将会使用到索引,而第二句因为以通配符开头,所以不会用到索引(模糊查询通配符:%
匹配任意数量的字符,_
匹配一个字符)
- 对于使用
or
的逻辑语句,必须两边都是索引才会用索引,不然其中一边不是索引,既然都得遍历一遍,也就没必要索引了