Mysql索引优化(一)_索引类型

索引对于良好的性能很是关键,尤为是在数据量愈来愈大的时候。恰当的索引对性能的帮助是很是巨大的,不恰当的索引不由不能对性提高有帮助,当数据量达到必定级别的时候还可能形成性能的降低。因此了解索引对 Mysql性能优化有着相当重要的做用。

Mysql索引基本类型有 B-Tree,哈希索引,全文索引,空间数据索引(R-Tree)。其中B-Tree哈希全文索引是咱们常常用到的。sql

B-Tree索引

B-Tree索引是咱们口中常常说的索引类型(有些存储引擎中使用的是B+Tree。如InnoDB)。每一个引擎对于BTREE索引使用方式是不同的。
性能优化

  • MyISAM引擎使用的是前置压缩技术,这样索引会变的很小。而InnoDB则是按照原有的数据格式来存储的。
  • MyISAM索引是经过数据的物理位置来找到被索引的行,而InnoDB则是根据被索引的行的主键来找到被索引行的。

B-Tree索引的全部值都是按顺序存储的,而且每一个叶子节点到根节点的距离是相同的。下面给出一个简单的示意图性能

图片描述

假设有下表:优化

CREATE TABLE student(
    first_name varchar(20) not null,
    last_name varchar(20) not null,
    age tinyint(3) not null,
    created_at timestamp not null,
    key(first_name ,last_name)
);

可使用到B-Tree索引的查询spa

  • 全值匹配 全值匹配指对索引中的全部列进行匹配。如查询姓名是 zhang san的人 select * from student where first_name='zhang' and last_name='san'; 这里使用了索引的第一列与第二列
  • 匹配最左前缀,如查询姓为的人 select * from student where first_name='zhang' ;这里使用了索引的第一列
  • 匹配列前缀,也能够值匹配某一列的开头部分,如 select * from student where first_name='zha' ;这里使用了索引的第一列
  • 匹配范围值,如 select * from student where first_name>'bao' and first_name<'zhang';这样也会使用到索引的第一列
  • 只访问索引的查询,若是查询条件是 select first_name,last_name from student where first_name='zhang' ;那么查询就只会访问索引,而不会再去根据主键回表查询数据。
这里须要注意的是; B-Tree 索引须要根据最左前缀查询,若是不是按照索引的最左列开始查询,那么是不会使用到索引的。例如:
select * from student where last_name='san';
select * from student where first_name like '%ha%';
这样的 sql是没办法命中索引的。对于第二条 sql若是须要使用索引,那么应该改成 select * from student where first_name like 'ha%';
哈希索引

哈希索引是基于哈希表实现的,只有精确匹配索引全部列的查询才会使用到索引,只有Memory引擎才支持哈希索引。
假设有下表:指针

CREATE TABLE student(
    first_name varchar(20) not null,
    last_name varchar(20) not null,
    age tinyint(3) not null,
    created_at timestamp not null,
    key using hash(first_name)
) engine=memory;

若是咱们要执行select last_name from student where first_name='zhang';,Mysql会先计算zhang的哈希值,而后用该值寻找对应的记录指针,最后再去比较first_name是否等于zhang
由于哈希索引只存储对于的哈希值和行指针,因此哈希索引的结构很紧凑,查询速度很是快。可是也有一些缺点。code

  • 由于哈希索引只有哈希值与指针,因此每次查询必须回表去读取数据行。
  • 由于哈希索引不是按照索引值顺序存储的,因此哈希索引也不能用于排序。
  • 哈希索引不支持部分索引列查询,好比 将student表是索引 改成 hash(first_name,last_name),那么查询必须用到first_name,last_name才会使用到索引。
  • 哈希索引只支持等值比较,因此<,>等范围查询是不会使用到索引的。
  • 哈希索引也会存在哈希冲突,当出现冲突的时候,查询效率就很下降不少。

图片描述