浅谈Mysql主键索引与非主键索引区别

目录
  • 什么是索引
  • 主键索引和普通索引的区别
  • 索引具体采用的哪种数据结构
  • innodb使用的b+ tree的索引模型,那么为什么采用b+ 树?这和hash索引比较起来有什么优缺点?
  • b+ tree的叶子节点都可以存哪些东西?
  • 聚簇索引和非聚簇索引,在查询数据的时候有区别?
  • index condition pushdown(索引下推)
  • 查询优化器
  • 关于索引的题

什么是索引

mysql官方索引的定义:索引(index)是帮助mysql高效获取数据的数据结构,索引的目的在于提高查询效率,类比字典;实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,索引列也是要占用空间。

主键索引和普通索引的区别

1.主键索引索引着数据,然而普通索引索引着主键id值(这是在innodb中,但是如果是myisam中,主键索引和普通索引是没有区别的都是直接索引着数据)
2.当你查询用的是where id=x 时,那只需要扫描一遍主键索引,然后拿到相应数据,但是如果是查询的普通索引的话,那么会先扫描一次普通索引,拿到主键值,然后再去扫主键索引,拿到所需要的数据,这个过程叫做回表

索引具体采用的哪种数据结构

常见的mysql主要有两种结构:hash索引和b+ tree索引,我们使用的是innodb引擎,默认的是b+树

innodb使用的b+ tree的索引模型,那么为什么采用b+ 树?这和hash索引比较起来有什么优缺点?

b+ tree索引和hash索引区别 哈希索引适合等值查询,但是不无法进行范围查询 哈希索引没办法利用索引完成排序 哈希索引不支持多列联合索引的最左匹配规则 如果有大量重复键值得情况下,哈希索引的效率会很低,因为存在哈希碰撞问题

b+ tree的叶子节点都可以存哪些东西?

在 innodb 里,索引b+ tree的叶子节点存储了整行数据的是主键索引,也被称之为聚簇索引。而索引b+ tree的叶子节点存储了主键的值的是非主键索引,也被称之为非聚簇索引。

聚簇索引和非聚簇索引,在查询数据的时候有区别?

聚簇索引查询会更快
因为主键索引树的叶子节点直接就是我们要查询的整行数据了。而非主键索引的叶子节点是主键的值,查到主键的值以后,还需要再通过主键的值再进行一次查询,这个过程称作回表。
非主键索引一定会查询多次吗?
覆盖索引也可以只查询一次,覆盖索引(covering index)指一个查询语句的执行只用从索引中就能够取得,不必从数据表中读取。也可以称之为实现了索引覆盖。 当一条查询语句符合覆盖索引条件时,mysql只需要通过索引就可以返回查询所需要的数据,这样避免了查到索引后再返回表操作,减少i/o提高效率。 如,表covering_index_sample中有一个普通索引 idx_key1_key2(key1,key2)。当我们通过sql语句:select key2 from covering_index_sample where key1 = ‘keytest’;的时候,就可以通过覆盖索引查询,无需回表。

index condition pushdown(索引下推)

mysql 5.6引入了索引下推优化,默认开启,使用set optimizer_switch = ‘index_condition_pushdown=off’;可以将其关闭。官方文档中给的例子和解释如下: people表中(zipcode,lastname,firstname)构成一个索引

where zipcode=‘95054' and lastname like ‘%etrunia%' and address like ‘%main street%';

如果没有使用索引下推技术,则mysql会通过zipcode=’95054’从存储引擎中查询对应的数据,返回到mysql服务端,然后mysql服务端基于lastname like ‘%etrunia%’和address like ‘%main street%’来判断数据是否符合条件。 如果使用了索引下推技术,则mysql首先会返回符合zipcode=’95054’的索引,然后根据lastname like ‘%etrunia%’筛选出符合条件的索引后再返回到mysql服务端,然后mysql服务端基于address like ‘%main street%’来判断数据是否符合条件,这样返回给mysql服务端的索引数又会减少。有了索引下推优化,可以在有like条件查询的情况下,减少回表次数。

查询优化器

一条sql语句的查询,可以有不同的执行方案,至于最终选择哪种方案,需要通过优化器进行选择,选择执行成本最低的方案。 在一条单表查询语句真正执行之前,mysql的查询优化器会找出执行该语句所有可能使用的方案,对比之后找出成本最低的方案。这个成本最低的方案就是所谓的执行计划。 优化过程大致如下: 1、根据搜索条件,找出所有可能使用的索引 2、计算全表扫描的代价 3、计算使用不同索引执行查询的代价 4、对比各种执行方案的代价,找出成本最低的那一个

关于索引的题

create table `geek` (
  `a` int(11) not null,
  `b` int(11) not null,
  `c` int(11) not null,
  `d` int(11) not null,
  primary key (`a`,`b`),
  key `c` (`c`),
  key `ca` (`c`,`a`),
  key `cb` (`c`,`b`)
) engine=innodb;

由于历史原因,这个表需要 a、b 做联合主键。
那意味着,单独在字段 c 上创建一个索引,就已经包含了三个字段,为什么要创建“ca”“cb”这两个索引?

select * from geek where c=n order by a limit 1;
select * from geek where c=n order by b limit 1;

问题:这位同事的解释对吗? 哪些索引没有必要,可以删除?

答案:

(1) 主键 a,b 的聚簇索引组织顺序相当于 order by a,b ,也就是先按 a 排序,再按 b 排序,c 无序。

–a–|–b–|–c–|–d–
1 2 3 d
1 3 2 d
1 4 3 d
2 1 3 d
2 2 2 d
2 3 4 d

(2) 索引 ca 的组织是先按 c 排序,再按 a 排序,同时记录主键。

–c–|–a–|–主键部分b– (注意,这里不是 ab,而是只有 b)
2 1 3
2 2 2
3 1 2
3 1 4
3 2 1
4 2 3

上面的这个索引ca 与索引c 的数据是一模一样的。

(3) 索引 cb 的组织是先按 c 排序,在按 b 排序,同时记录主键

–c–|–b–|–主键部分a– (同上)
2 2 2
2 3 1
3 1 2
3 2 1
3 4 1
4 3 2

所以结论是ca可以去掉,cb保留。

到此这篇关于浅谈mysql主键索引与非主键索引区别的文章就介绍到这了,更多相关mysql主键索引与非主键索引内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐