Mysql 索引

索引介绍

相当于目录,能够提高查询性能。但因为其会再建一个空间来存放这些索引,所以会消耗部分空间,并且在对数据进行插入、更新等操作时,也会自动对索引目录进行修改,因此某些情况下也会降低性能

作用

通过设置关键字和数据位置的映射关系,从而加快检索,是较为常用的优化手段

关键字

从数据中心提取,用于标识、检索数据的特定内容

索引为什么快
  • 索引相对于数据本身,数据量小
  • 关键字都是排好序的,通过遍历也可以确定位置

索引类型

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%";

此时namework是成对出现的,那么设置联合索引(name, work)就相比分别对namework设置索引的效率更高

排序机制

对于多个字段的联合索引,其排序是先根据从左边第一个字段开始排序,如果字段相同,在比较右边的下一个字段

前缀索引

概念

默认索引都是使用字段的全部内容进行索引,但在一些情况下,我们可以仅需要使用到字段的前几个字符来建立索引,例如一些加密算法计算的字段,其前几位基本就可以保证数据的唯一性,此时就适合使用前缀索引。使用前缀能够用更少的空间更高效的建立索引,并且索引长度越小速度越快

前缀索引适合情况判断

想要判断某个字段是否适合使用前缀索引,可以通过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的逻辑语句,必须两边都是索引才会用索引,不然其中一边不是索引,既然都得遍历一遍,也就没必要索引了

你可能感兴趣的:(Mysql 索引)