1、大大减少了服务器需要扫描的数据量
2、帮助服务器避免排序和临时表
3、将随机io变成顺序io
1、快速查找匹配WHERE子句的行
2、从consideration中消除行,如果可以在多个索引之间进行选择,mysql通常会使用找到最少行的索引
3、如果表具有多列索引,则优化器可以使用索引的任何最左前缀来查找行
4、当有表连接的时候,从其他表检索行数据
5、查找特定索引列的min或max值
6、如果排序或分组时在可用索引的最左前缀上完成的,则对表进行排序和分组
7、在某些情况下,可以优化查询以检索值而无需查询数据行
主键索引
主键唯一且非空,相当于数据库帮忙创建的特殊的唯一索引
InnoDB聚集索引的叶子节点存储行记录,因此, InnoDB必须且只有一个聚集索引:
(1)如果表定义了主键,则PK就是聚集索引;
(2)如果表没有定义主键,则第一个非空唯一索引(not NULL unique)列是聚集索引;
(3)否则,InnoDB会创建一个隐藏的row-id作为聚集索引;(这个row-id是6位的,所以尽量我们指定主键)
唯一索引
普通索引
全文索引
fulltext,一般用在varchar,text上,用的较少
组合索引
对于一些经常需要组合查询的条件列,就可以把多个列组合起来共同创建一个所以哦那
MyISAM和InnoDB 都是是B+树;枝干上不存数据,叶子节点存数据
说来话长,下面单独拿出来写
create table staffs(
id int primary key auto_increment,
name varchar(24) not null default '' comment '姓名',
age int not null default 0 comment '年龄',
pos varchar(20) not null default '' comment '职位',
add_time timestamp not null default current_timestamp comment '入职时间'
) charset utf8 comment '员工记录表';
-----------
alter table staffs add index idx_nap(name, age, pos);
全值匹配指的是和索引中的所有列进行匹配
explain select * from staffs where name = ‘July’ and age = ‘23’ and pos = ‘dev’;
只匹配前面的几列
explain select * from staffs where name = ‘July’ and age = ‘23’;
explain select * from staffs where name = ‘July’;
可以匹配某一列的值的开头部分
explain select * from staffs where name like ‘J%’;
explain select * from staffs where name like ‘%y’;
可以查找某一个范围的数据
explain select * from staffs where name > ‘Mary’;
可以查询第一列的全部和第二列的部分
explain select * from staffs where name = ‘July’ and age > 25;
查询的时候只需要访问索引,不需要访问数据行,本质上就是覆盖索引
explain select name,age,pos from staffs where name = ‘July’ and age = 25 and pos = ‘dev’;
MySQL官网虽然说的B-Tree,但其实是B+树,也许国外没有把他俩区分的这么开.
如果我们自己设计索引,怎么设计?
数据存储在磁盘文件中,我们想定位一组数据,首先要知道存储文件的路径,还要知道该数据在文件的偏移量offset(cursor,seek)
即我们设计索引的话,要记录下数据对应的 1.文件的路径;2.偏移量
想记录这俩东西,需要用啥数据结构?
hash,二叉树,红黑树,B树,B+树,为啥MySQL的InnoDB选择了B+树?
InnoDB是通过B+Tree结构对主键创建索引,然后叶子节点中存储记录,如果没有主键,那么会选择唯一键,如果没有唯一键,那么会生成一个6位的row_id来作为主键;
如果是非主键索引,那么在叶子节点中存储的是该记录的主键(和该索引自己),如果查询其他列数据 就需要通过主键索引找到对应的记录,叫做回表;
主键索引的叶子节点中存储的是整行数据,不需要回表.
MyISAM 和 InnoDB 虽然都是使用B+树,但他们格式是不一样的
MyISAM 会把数据和索引分开存储;InnoDB会把他们放一起
MyISAM 的节点中的data,存储的是真正数据的地址,根据这个地址去对应的MYD文件里面找数据
InnoDB节点中的data就是真实的数据行